Cookpad summer internship 2019 - API

Cookpad summer internship 2019 - API

A lecture slide for https://internship.cookpad.com/2019/summer/ (Day 3 ).

3b36493b4296ebeb219bcd3ffab3aa2b?s=128

Kenju Wagatsuma

August 21, 2019
Tweet

Transcript

  1. Cookpad Internship 2019 10 Day Tech: API Kenju Wagatsuma KOBA789

    Yoshiaki Yamada
  2. 今日は API です • 講師
 ◦ @kenju_wagatsuma
 • TA
 ◦

    @KOBA789
 ◦ @ymd

  3. 講師: @kenju_wagatsuma • 我妻 謙樹(Kenju Wagatsuma)
 • メディアプロダクト開発部マーケティングサービス開発グ ループ
 •

    広告配信サーバー・入稿システム・リアルタイムログ基盤等 広告にまつわるシステムの保守運用

  4. 広告関連システム概要 Operation Team Data Warehouse Ad Creative Optimization Ad Campaign

    Ordering Service Ad Delivery Service Targeting Service Delivery Metadata Mobile Client Ad Creatives log
  5. Linux OS Docker, Terraform, Jenkins DevOps Nginx, Fluentd, ELB Infra

    Ruby Rails TypeScript React.js GraphQL Apollo Ruby Rails Go AWS ElastiCache AWS DynamoDB Service Mesh Envoy Python AWS APIGateway AWS Lambda Tableau Application SQL AWS Redshift AWS Athena Ruby Python AWS Kinesis AWS DynamoDB AWS Lambda Batch Layer Streaming Layer Ad creative admin service Ad delivery service Logging Machine Learning 広告関連システム選定技術一覧
  6. TA: @KOBA789 • 平成7年8月9日生まれで789
 • ビッグデータをいい感じにする仕事(それ以外もやる)
 • データベース・トランザクション・分散システム
 • 代表作:

    Prism(分散ログストレージ)
 • よく書く: Java, Rust, TypeScript

  7. TA: @ymd • 山田 良明
 • 研究開発部エンジニア
 • LambdaとDynamoDBを使ってスマートスピーカー
 向けサービスを開発しています


  8. Timeline • 1000-1130 講義パート A(基礎編)
 • 1130-1300 Handson
 • 1300-1400

    ランチ
 • 1300-1400 講義パート B(応用編)
 • 1400-1830 Exercise
 ※ 休憩は各位適宜取得してください

  9. tl;dr • Backend-For Frontend(以下:BFF) を Node.js / GraphQL / TypeScript

    を使って開発します
 • 現場の実際の開発にかなり近い開発体験を経験することが できます

  10. NOTE • ハンズオン編は zoom で画面共有します
 ◦ WiFi 接続速度によって柔軟に対応しましょう
 • 後日インフラの日に触れる技術要素は

    Blackbox で行きま すので心配しないでください
 ◦ e.x. hako, SAM, DynamoDB, facebook/dataloader, etc.

  11. 講義パート A(基礎編)

  12. 講義パート A(基礎編)でやること • 基礎技術詳解をします
 ◦ BFF
 ◦ GraphQL


  13. Keywords • Microservices
 • レガシーと新システムの両立
 • Ruby/Rails だけでない、幅広い技術選定
 • Serverless


  14. BFF

  15. BFF at Cookpad https://techlife.cookpad.com/entry/2019-orcha-bff

  16. What’s BFF? • Pattern: Backends For Frontends by Sam Newman,

    the author of “Building Microservices” • Definition: “Single-purpose Edge Services for UIs and external parties” https://samnewman.io/patterns/architectural/bff/
  17. One of “API-Gateway” Patterns https://microservices.io/patterns/apigateway.html BFF は API-Gateway Patterns と呼ばれる設計パ

    ターンの一種。 ※ RESTful API / GraphQL は実装の詳細である。 GraphQL だけが BFF では ない点に注意。
  18. Legacy New BFR Backend for Resource Frontend Resource Resource Legacy

    Usecase New Usecase
  19. Legacy New RESTful API, GraphQL Schema BFR Backend for Resource

    BFF Backend for Frontend Frontend Resource Resource Legacy Usecase New Usecase
  20. GraphQL

  21. About GraphQL • API のためのクエリ言語の仕様
 • Facebook で 2012 年から開発され、2015

    年に OSS 化、そ の後 GraphQL Foundation が設立されるなどコミュニティも 拡大
 • JavaScript や Ruby を始めとした実装多数

  22. BFF x GraphQL 以下の Backend Resources を Client に対 して隠蔽する設計パターン

    • RDBMS/NoSQL などの Datasource • 新規システム • 既存システム • 3rd-Party API https://www.howtographql.com/basics/3-big-picture/
  23. schema.graphql • 型とクエリ操作を定義した宣言ファイル
 • 手動で書く場合、DSL から自動生成する場合(e.g. graphql-ruby)、型定義から自動生成する場合(e.g. graphql-codegen)などのパターンが有る


  24. Query • データを取得するための操作を定義
 • 欲しいデータの、欲しいフィールドを宣言的に書く
 ▪ 利点
 • Over-fetching /

    Under-fetching を防ぐ
 • クライアント開発において欲しいデータを宣言的 に書けることで保守性が向上

  25. Mutation • データの作成・削除・更新など副作用をもたらす操作を定義
 • RESTful API で言うところの POST/DELETE/PUT/PATCH に相当することが多い


  26. Introspection • GraphQL server に対して、どのような型システムやクエリ操 作を提供しているかを問い合わせるための、GraphQL の仕 様
 • デバッグや

    docs 生成、ツール作成時等に多様
 • スキーマ、型、フィールド情報などが取得できる

  27. 具体例 実際の API を利用して具体例を見せます
 • schema.graphql
 • GraphQL Playground
 •

    Query Example

  28. Handson

  29. Handson でやること • アプリのシステム概要を紹介します
 • ハンズオン演習内容を発表します


  30. pantry Koresuki (Likes) BFF (GraphQL) Schema pantry AWS API Gateway

    Mobile Client AuthoCenter AWS Lambda AWS DynamoDB voyager user backend
  31. System Architecture

  32. クライアント側仕様 • シンプルな mini Cookpad を実装します
 ◦ レシピ一覧
 ◦ レシピ詳細


    ◦ いいね一覧

  33. クライアント側仕様 • Cookpad 本体アプリも利用している同等の Backend Service を利用します
 ◦ “pantry” と呼ばれる


    • 「いいね」機能はフルスクラッチで実装します
 ◦ AWS サービス群を利用した Serverless 構成

  34. List
 Detail
 Likes


  35. pantry Koresuki (Likes) BFF (GraphQL) Schema pantry AWS API Gateway

    Mobile Client AuthoCenter AWS Lambda AWS DynamoDB voyager user backend BFF & Koresuki を
 実装します

  36. 前提条件 以下の新システムを開発する
 • BFF Application
 ◦ pantry & Koresuki へのリクエスト


    • Koresuki Application
 ◦ 「いいね」機能の実装

  37. 制約条件 以下の既存システムは実装を加えることができない
 • pantry
 ◦ pantry が提供する API を使うしか無い
 •

    AuthoCenter
 ◦ 認証フローを拡張することはできない

  38. “Simple” !== “Easy” • Likes の状態はどうやって保存する?
 • pantry と Koresuki

    の結果をどう JOIN する?
 • GraphQL のキャッシュが必要になったらどうしたらよい?
 • 認証 (Authorization) に失敗したときは何を表示する?
 • pantry が死んだ時の retry 戦略はどうする?
 • Koresuki はどうスケールさせる?
 • NoSQL におけるインデックスはどう貼る?
 • 非機能要件をどこまで実装できる?
 • ID Token の検証が Bottleneck になった時、どこを改善する?
 • etc.

  39. 関連システムの解説

  40. Systems • Pantry
 • AuthoCenter
 • AWS API Gateway
 •

    AWS Lambda
 • AWS DynamoDB

  41. Pantry • Cookpad レシピサービスのリソースを HTTP で操作するた めの API Server
 •

    May 2013~ から開発スタートされた Rails app
 • レシピ一覧、レシピ詳細、カテゴリ一覧、殿堂入りレシピ、検 索、人気順、... etc.

  42. Pantry • 実際の Cookpad で利用されている「本物」です
 • Summer Internship 用に、インフラ定義だけ変えた Staging

    版を deploy しています

  43. AuthCenter • OAuth2 認可を行うための Web application
 • RFC 6749 (The

    OAuth 2.0 Authorization Framework) に 則った基本に加え、固有の拡張がいくつか存在する
 • アクセストークンの発行, アクセストークンの検証

  44. AuthoCenter(通称:大嘘センター) • @KOBA789 謹製, Rust 製
 • Summer Internship 用に作られた

    AuthCenter を模した Web application
 • 任意の user_id を渡すと ID Token が発行される

  45. ID Token • JSON Web Token (JWT) を署名したもの
 ◦ RFC7519


    • 署名方法
 ◦ JSON Web Signature (JWS) RFC7515
 ◦ JSON Web Key (JWK) RFC7517

  46. ID Token header
 body
 signature
 .
 .
 Base64 Encode された

    JSON Web Token (JWT) 
 
 { “iss”: “https://….”, “sub”: “16672509”, .... } ※ JWS で JWT を署名した形式 

  47. AWS API Gateway • HTTP な RESTful API のためのマネージドサービス
 •

    Canary Release や認証機能等 API 開発には欠かせない機 能提供の他、CloudWatch と連携した Logging/Monitoring/Alerting などが有用

  48. AWS Lambda • サーバー環境のセットアップなしに、任意のプログラムを実 行できるマネージドサービス
 • ビジネスロジックの開発に集中することができる
 • Java/Go/PowerShell/Node.js/C#/Python/Ruby の言語を

    Native でサポート

  49. AWS DynamoDB • Amazon で高可用性・拡張性を兼ね備 えた分散 KVS として開発された Dynamo の商用版


    • ショッピングカート機能のバックエンド などに利用

  50. Handson

  51. Handson • 以下の内容に沿って解説していきます
 ◦ ghe.ckpd.co/pages/tech/2019-summer-internship/api


  52. 講義パート B: 応用編

  53. 講義パート B: 応用編でやること • ハンズオン応用編の内容を紹介します
 • ハンズオン応用編を進めるにあたって必要な技術を解説し ます


  54. Keywords • More GraphQL Specification
 • Error Handling w/ GraphQL


    • Relay Cursor Connection
 • Kill N+1

  55. More GraphQL Specification https://ghe.ckpd.co/pages/tech/2019-summer-internship/bff/graphql_tips 
 • Null / Non-Null
 •

    Interface
 • Union
 • Scalar
 • Enum
 • Directive

  56. Error Handling w/ GraphQL • HTTP Status = 200 OK

    のまま、“errors” にエラーの Stack traces を含める
 ◦ https://graphql.github.io/graphql-spec/June2018/#sec-Errors
 • あくまで Best Practices(apollo-server や graphql-ruby など 多くのツールが従っている)

  57. Error Handling w/ GraphQL • 理由
 ◦ 例)pantry へのリクエストがエラーになったからって、他 の

    Backend Resources からのレスポンスなど全ての フィールドが エラーになると、GraphQL を BFF としてら 使う旨味が半減
 ◦ 返せるものは返す

  58. 例)
 前提条件
 • “name” field が Non-Null
 • id=1002 のデータは、”name”

    field が Null
 結果
 • id=1001, 1003 の結果は返却され る
 • “errors” field に id=1002 のデー タが取得できない理由を格納。ど う処理するかはクライアント次第

  59. Relay Cursor Connection • https://facebook.github.io/relay/graphql/connections.htm
 • Pagination に関する Practice の一つ


    • GraphQL Framework の一つであり、Facebook が主だって 開発している Relay で実装されている
 • Connection/Edge/Node/PageInfo

  60. Example)
 • edges
 ◦ edge (node + cursor) の配列 


    • cursor
 ◦ カーソル。一連の Edges にアクセス する際の現在位置を表現 
 ◦ String に serialize 可能な型 
 • node
 ◦ Pagination で返却したいデータ 
 • pageInfo
 ◦ hasNextPage & endCursor 
 ◦ hasPreviousPage & startCursor 

  61. graphql/dataloader • Caching
 ◦ 同じ Request Parameters のレスポンス結果は、リクエス トごとにキャッシュして再利用
 •

    Batching
 ◦ Promise (JavaScript の標準 API)を利用して resolver を遅延評価、同じリクエストは一括処理(batch)する

  62. 実践パート B: Exercise

  63. 総括

  64. 総括 • 総括 by TA
 • 総括 by 講師


  65. Thank you!