Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Cookpad summer internship 2019 - API

Cookpad summer internship 2019 - API

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

Ken Wagatsuma

August 21, 2019
Tweet

More Decks by Ken Wagatsuma

Other Decks in Programming

Transcript

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

    View full-size slide

  2. 今日は API です
    ● 講師

    ○ @kenju_wagatsuma

    ● TA

    ○ @KOBA789

    ○ @ymd


    View full-size slide

  3. 講師: @kenju_wagatsuma
    ● 我妻 謙樹(Kenju Wagatsuma)

    ● メディアプロダクト開発部マーケティングサービス開発グ
    ループ

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


    View full-size slide

  4. 広告関連システム概要
    Operation Team
    Data Warehouse
    Ad Creative
    Optimization
    Ad Campaign
    Ordering Service
    Ad Delivery
    Service
    Targeting Service
    Delivery Metadata
    Mobile Client
    Ad Creatives
    log

    View full-size slide

  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
    広告関連システム選定技術一覧

    View full-size slide

  6. TA: @KOBA789
    ● 平成7年8月9日生まれで789

    ● ビッグデータをいい感じにする仕事(それ以外もやる)

    ● データベース・トランザクション・分散システム

    ● 代表作: Prism(分散ログストレージ)

    ● よく書く: Java, Rust, TypeScript


    View full-size slide

  7. TA: @ymd
    ● 山田 良明

    ● 研究開発部エンジニア

    ● LambdaとDynamoDBを使ってスマートスピーカー

    向けサービスを開発しています


    View full-size slide

  8. Timeline
    ● 1000-1130 講義パート A(基礎編)

    ● 1130-1300 Handson

    ● 1300-1400 ランチ

    ● 1300-1400 講義パート B(応用編)

    ● 1400-1830 Exercise

    ※ 休憩は各位適宜取得してください


    View full-size slide

  9. tl;dr
    ● Backend-For Frontend(以下:BFF) を Node.js / GraphQL
    / TypeScript を使って開発します

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


    View full-size slide

  10. NOTE
    ● ハンズオン編は zoom で画面共有します

    ○ WiFi 接続速度によって柔軟に対応しましょう

    ● 後日インフラの日に触れる技術要素は Blackbox で行きま
    すので心配しないでください

    ○ e.x. hako, SAM, DynamoDB, facebook/dataloader, etc.


    View full-size slide

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

    View full-size slide

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

    ○ BFF

    ○ GraphQL


    View full-size slide

  13. Keywords
    ● Microservices

    ● レガシーと新システムの両立

    ● Ruby/Rails だけでない、幅広い技術選定

    ● Serverless


    View full-size slide

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

    View full-size slide

  15. 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/

    View full-size slide

  16. One of “API-Gateway” Patterns
    https://microservices.io/patterns/apigateway.html
    BFF は API-Gateway
    Patterns と呼ばれる設計パ
    ターンの一種。
    ※ RESTful API / GraphQL
    は実装の詳細である。
    GraphQL だけが BFF では
    ない点に注意。

    View full-size slide

  17. Legacy New
    BFR
    Backend for Resource
    Frontend
    Resource Resource
    Legacy
    Usecase
    New
    Usecase

    View full-size slide

  18. Legacy New
    RESTful API, GraphQL
    Schema
    BFR
    Backend for Resource
    BFF
    Backend for Frontend
    Frontend
    Resource Resource
    Legacy
    Usecase
    New
    Usecase

    View full-size slide

  19. About GraphQL
    ● API のためのクエリ言語の仕様

    ● Facebook で 2012 年から開発され、2015 年に OSS 化、そ
    の後 GraphQL Foundation が設立されるなどコミュニティも
    拡大

    ● JavaScript や Ruby を始めとした実装多数


    View full-size slide

  20. BFF x GraphQL
    以下の Backend Resources を Client に対
    して隠蔽する設計パターン
    ● RDBMS/NoSQL などの Datasource
    ● 新規システム
    ● 既存システム
    ● 3rd-Party API
    https://www.howtographql.com/basics/3-big-picture/

    View full-size slide

  21. schema.graphql
    ● 型とクエリ操作を定義した宣言ファイル

    ● 手動で書く場合、DSL から自動生成する場合(e.g.
    graphql-ruby)、型定義から自動生成する場合(e.g.
    graphql-codegen)などのパターンが有る


    View full-size slide

  22. Query
    ● データを取得するための操作を定義

    ● 欲しいデータの、欲しいフィールドを宣言的に書く

    ■ 利点

    ● Over-fetching / Under-fetching を防ぐ

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


    View full-size slide

  23. Mutation
    ● データの作成・削除・更新など副作用をもたらす操作を定義

    ● RESTful API で言うところの POST/DELETE/PUT/PATCH
    に相当することが多い


    View full-size slide

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

    ● デバッグや docs 生成、ツール作成時等に多様

    ● スキーマ、型、フィールド情報などが取得できる


    View full-size slide

  25. 具体例
    実際の API を利用して具体例を見せます

    ● schema.graphql

    ● GraphQL Playground

    ● Query Example


    View full-size slide

  26. Handson でやること
    ● アプリのシステム概要を紹介します

    ● ハンズオン演習内容を発表します


    View full-size slide

  27. pantry Koresuki (Likes)
    BFF (GraphQL)
    Schema
    pantry
    AWS API Gateway
    Mobile Client AuthoCenter
    AWS Lambda
    AWS DynamoDB
    voyager
    user
    backend

    View full-size slide

  28. System Architecture

    View full-size slide

  29. クライアント側仕様
    ● シンプルな mini Cookpad を実装します

    ○ レシピ一覧

    ○ レシピ詳細

    ○ いいね一覧


    View full-size slide

  30. クライアント側仕様
    ● Cookpad 本体アプリも利用している同等の Backend
    Service を利用します

    ○ “pantry” と呼ばれる

    ● 「いいね」機能はフルスクラッチで実装します

    ○ AWS サービス群を利用した Serverless 構成


    View full-size slide

  31. List

    Detail

    Likes


    View full-size slide

  32. pantry Koresuki (Likes)
    BFF (GraphQL)
    Schema
    pantry
    AWS API Gateway
    Mobile Client AuthoCenter
    AWS Lambda
    AWS DynamoDB
    voyager
    user
    backend
    BFF & Koresuki を

    実装します


    View full-size slide

  33. 前提条件
    以下の新システムを開発する

    ● BFF Application

    ○ pantry & Koresuki へのリクエスト

    ● Koresuki Application

    ○ 「いいね」機能の実装


    View full-size slide

  34. 制約条件
    以下の既存システムは実装を加えることができない

    ● pantry

    ○ pantry が提供する API を使うしか無い

    ● AuthoCenter

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


    View full-size slide

  35. “Simple” !== “Easy”
    ● Likes の状態はどうやって保存する?

    ● pantry と Koresuki の結果をどう JOIN する?

    ● GraphQL のキャッシュが必要になったらどうしたらよい?

    ● 認証 (Authorization) に失敗したときは何を表示する?

    ● pantry が死んだ時の retry 戦略はどうする?

    ● Koresuki はどうスケールさせる?

    ● NoSQL におけるインデックスはどう貼る?

    ● 非機能要件をどこまで実装できる?

    ● ID Token の検証が Bottleneck になった時、どこを改善する?

    ● etc.


    View full-size slide

  36. 関連システムの解説

    View full-size slide

  37. Systems
    ● Pantry

    ● AuthoCenter

    ● AWS API Gateway

    ● AWS Lambda

    ● AWS DynamoDB


    View full-size slide

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

    ● May 2013~ から開発スタートされた Rails app

    ● レシピ一覧、レシピ詳細、カテゴリ一覧、殿堂入りレシピ、検
    索、人気順、... etc.


    View full-size slide

  39. Pantry
    ● 実際の Cookpad で利用されている「本物」です

    ● Summer Internship 用に、インフラ定義だけ変えた Staging
    版を deploy しています


    View full-size slide

  40. AuthCenter
    ● OAuth2 認可を行うための Web application

    ● RFC 6749 (The OAuth 2.0 Authorization Framework) に
    則った基本に加え、固有の拡張がいくつか存在する

    ● アクセストークンの発行, アクセストークンの検証


    View full-size slide

  41. AuthoCenter(通称:大嘘センター)
    ● @KOBA789 謹製, Rust 製

    ● Summer Internship 用に作られた AuthCenter を模した Web
    application

    ● 任意の user_id を渡すと ID Token が発行される


    View full-size slide

  42. ID Token
    ● JSON Web Token (JWT) を署名したもの

    ○ RFC7519

    ● 署名方法

    ○ JSON Web Signature (JWS) RFC7515

    ○ JSON Web Key (JWK) RFC7517


    View full-size slide

  43. ID Token
    header
 body
 signature

    .
 .

    Base64 Encode された
    JSON Web Token (JWT) 


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


    View full-size slide

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

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


    View full-size slide

  45. AWS Lambda
    ● サーバー環境のセットアップなしに、任意のプログラムを実
    行できるマネージドサービス

    ● ビジネスロジックの開発に集中することができる

    ● Java/Go/PowerShell/Node.js/C#/Python/Ruby の言語を
    Native でサポート


    View full-size slide

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

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


    View full-size slide

  47. Handson
    ● 以下の内容に沿って解説していきます

    ○ ghe.ckpd.co/pages/tech/2019-summer-internship/api


    View full-size slide

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

    View full-size slide

  49. 講義パート B: 応用編でやること
    ● ハンズオン応用編の内容を紹介します

    ● ハンズオン応用編を進めるにあたって必要な技術を解説し
    ます


    View full-size slide

  50. Keywords
    ● More GraphQL Specification

    ● Error Handling w/ GraphQL

    ● Relay Cursor Connection

    ● Kill N+1


    View full-size slide

  51. More GraphQL Specification
    https://ghe.ckpd.co/pages/tech/2019-summer-internship/bff/graphql_tips 

    ● Null / Non-Null

    ● Interface

    ● Union

    ● Scalar

    ● Enum

    ● Directive


    View full-size slide

  52. 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 など
    多くのツールが従っている)


    View full-size slide

  53. Error Handling w/ GraphQL
    ● 理由

    ○ 例)pantry へのリクエストがエラーになったからって、他
    の Backend Resources からのレスポンスなど全ての
    フィールドが エラーになると、GraphQL を BFF としてら
    使う旨味が半減

    ○ 返せるものは返す


    View full-size slide

  54. 例)

    前提条件

    ● “name” field が Non-Null

    ● id=1002 のデータは、”name” field
    が Null

    結果

    ● id=1001, 1003 の結果は返却され
    る

    ● “errors” field に id=1002 のデー
    タが取得できない理由を格納。ど
    う処理するかはクライアント次第


    View full-size slide

  55. Relay Cursor Connection
    ● https://facebook.github.io/relay/graphql/connections.htm

    ● Pagination に関する Practice の一つ

    ● GraphQL Framework の一つであり、Facebook が主だって
    開発している Relay で実装されている

    ● Connection/Edge/Node/PageInfo


    View full-size slide

  56. Example)

    ● edges

    ○ edge (node + cursor) の配列 

    ● cursor

    ○ カーソル。一連の Edges にアクセス
    する際の現在位置を表現 

    ○ String に serialize 可能な型 

    ● node

    ○ Pagination で返却したいデータ 

    ● pageInfo

    ○ hasNextPage & endCursor 

    ○ hasPreviousPage & startCursor 


    View full-size slide

  57. graphql/dataloader
    ● Caching

    ○ 同じ Request Parameters のレスポンス結果は、リクエス
    トごとにキャッシュして再利用

    ● Batching

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


    View full-size slide

  58. 実践パート B: Exercise

    View full-size slide

  59. 総括
    ● 総括 by TA

    ● 総括 by 講師


    View full-size slide