Slide 1

Slide 1 text

15分で分かった気になる GraphQL PHPer Kaigi 2019

Slide 2

Slide 2 text

Profile Twitter: @ichikawa_0829 株式会社メルカリ Backendエンジニア

Slide 3

Slide 3 text

GraphQLとは

Slide 4

Slide 4 text

https://developer.github.com/v4/explorer/

Slide 5

Slide 5 text

RESTの問題を解決するために作られた APIの為のクエリ言語

Slide 6

Slide 6 text

RESTの問題を解決するために作られた APIの為のクエリ言語

Slide 7

Slide 7 text

Appで必要なデータとResponseのデータ構造の乖離 “We were frustrated with the differences between the data we wanted to use in our apps and the server queries they required.” 9/14/2015 by Lee Byron https://graphql.org/blog/graphql-a-query-language/

Slide 8

Slide 8 text

Overfetching Clientのあるページで user情報の - name - image_uri だけ必要

Slide 9

Slide 9 text

Overfetching /user/1234 Response { “user” { “id”: 1234, “name”: “s-ichikawa”, “image_uri”: “https://xxx/img/1234”, “address”: “東京都A区XYZ”, “birthday”: “1986/08/29”, “gender”: “male”, ... } }

Slide 10

Slide 10 text

Overfetching /user/1234 Response { “user” { “id”: 1234, “name”: “s-ichikawa”, “image_uri”: “https://xxx/img/1234”, “address”: “東京都A区XYZ”, “birthday”: “1986/08/29”, “gender”: “male”, ... } } 必要なのはここだけ

Slide 11

Slide 11 text

Underfetching Clientのあるページで 指定したuserの友達一覧を出したい usersのfriends全員の - name - image_uri が必要

Slide 12

Slide 12 text

Underfetching /user/1234 Response { “user” { “id”: 1234, … “friends”: [ 2345, 3456, 4567, 5678 ] } }

Slide 13

Slide 13 text

Underfetching /user/2345 Response { “user” { “id”: 2345, “name”: “ichikawa_2”, “image_uri”: “https://xxx/img/2345”, … } }

Slide 14

Slide 14 text

Underfetching /user/2345 /user/3456 /user/4567 ・ ・ ・

Slide 15

Slide 15 text

Underfetching /user/2345 /user/3456 /user/4567 ・ ・ ・ Too many round trip

Slide 16

Slide 16 text

Underfetching /user_for_X/1234 Response { “user” { “id”: 1234, … “friends”: [ {“id”:2345, “name”:”bさん”, “image_uri”: “https://xxx/img/2345”}, {“id”:3456, “name”:”cさん”, “image_uri”: “https://xxx/img/3456”}, ] } }

Slide 17

Slide 17 text

似たようなエンドポイントの乱立 /user/{id} /user_for_X/{id} /user_for_Y/{id} /user_for_Z/{id} /user_for_admin/{id} …

Slide 18

Slide 18 text

GraphQLはどう課題解決するか - Appで必要なデータとResponseのデータ構造の乖離 - GraphQLではクエリとレスポンスの構造が似ているため、クエリを見ればレス ポンスの構造を推測しやすい

Slide 19

Slide 19 text

GraphQLはどう課題解決するか /graphql

Slide 20

Slide 20 text

GraphQLはどう課題解決するか Request query GetUser { user(id: “1234:) { name img friends { name img } } news { title link } } /graphql

Slide 21

Slide 21 text

GraphQLはどう課題解決するか Response {“data”: { “user”: { “name”: “aさん”, “img”: “https://xxx/img/2345”, “friends”: [ { “name”:”bさん”, “img”: “https://xxx/img/2345” } ] }, “news”: { “title”: “awesome GraphQL”, “link”: “https://xxx/news/1” } }} /graphql

Slide 22

Slide 22 text

Pros & Cons

Slide 23

Slide 23 text

GraphQLの強み - データ構造が理解しやすい - 複雑なデータが必要になってもRound Tripが抑えられる - エンドポイント管理が楽 - クライアントとサーバ間で型安全なコミュニケーションが可能 - 豊富な開発ツール類

Slide 24

Slide 24 text

GraphQLの弱み - いくつかの操作はRESTより面倒になる場合がある - ファイルアップロード - エラーハンドリング - モニタリング - Cache - パフォーマンス問題 - one-to-many、many-to-manyなデータを取得するような場合、サーバ側の 実装によってはN+1問題が発生する可能性がある

Slide 25

Slide 25 text

GraphQL Workflow

Slide 26

Slide 26 text

3つのOperation - Query - 情報を取得するために使用される - SQLでいうSELECT - Mutation - 情報を更新するために使用される - SQLでいうINSERT,UPDATE,DELETE - Subscription - 情報の変化をリアルタイムに取得するために使用される

Slide 27

Slide 27 text

クエリ言語とスキーマ - スキーマ - GraphQL APIの仕様を定義するためのもの - どのような処理ができてどのようなレスポンスが返るかを 決める - スキーマが決まるとDocsの自動生成や、Mockの作成が 可能になる - クエリ言語 - クライアントがGraphQL APIにリクエストするための言語 - PHPからDBを操作する際のSQLのようなイメージ

Slide 28

Slide 28 text

開発の流れ Schema Design Implements Monitoring Schema Client API Product Workflow Output

Slide 29

Slide 29 text

with Laravel & Lighthouse https://lighthouse-php.com/

Slide 30

Slide 30 text

Schema Design - レスポンスとして得たい型を定義する - 型名 - フィールド - 定義した型を得る為のオペレーションを定義する - 必要に応じてENUMやリクエストパラメータとして送信するた めの型(input型)なども定義できる

Slide 31

Slide 31 text

Schema Design - with laravel & lighthouse ● routes/graphql/schema.graphqlにScheme定義を書く どのクラスがItem型を解決するか 紐付ける

Slide 32

Slide 32 text

Implements - Client - Client側で必要なデータだけを指定してクエリを作成する - クエリをAPI Serverにリクエストする処理を書く - ResponseをページViewに反映させる処理等を書く

Slide 33

Slide 33 text

Implements - Client with laravel & lighthouse - 今回は横着して時間がないのでPlaygroundで代用 - https://github.com/prisma/graphql-playground

Slide 34

Slide 34 text

Implements - API - API側は採用する言語やライブラリに寄って実装方法は様々 - GraphQL処理系の実装は難易度が高いので、基本的には何かしらライブラリ を導入することになる - PHPではwebonyx/graphql-phpや - Laravelでやりたいならnuwave/lighthouse辺りが良さそう - オペレーションや型を解決する処理をResolverと呼び、ビジネ スロジックやデータアクセス処理を行う - Resolverの集合がGraphQL APIとも言える

Slide 35

Slide 35 text

Implements - API with laravel & lighthouse - Schemaで紐付けたResolverクラスを書く

Slide 36

Slide 36 text

No content

Slide 37

Slide 37 text

Monitoring - GraphQLのモニタリングはRESTの方式をそのまま使えない - エラートラッキング - これまで400系や500系を返していたエラーが発生しても200を返す - そういったエラーをそれぞれどう扱うかを決めて、エラー発生のイベントをトラッ キング - パフォーマンス - 単一エンドポイントのためクエリ単位で計測する - クエリ単位だけではなくResolver単位のパフォーマンス測定も必要

Slide 38

Slide 38 text

Conclusion

Slide 39

Slide 39 text

GraphQLとは - REST APIの問題を解決する為に開発されたクエリ言語 - 仕様は大きく分けてクエリとスキーマで構成される - 3種類のオペレーションがある - Query - Mutation - Subscription - 型付けされるため、クライアントとAPI間で型安全なやり取りが 可能になる - RESTを選択する方が適切なケースもある

Slide 40

Slide 40 text

Subscription Directive Architecture SchemaStitching PHPでどう始めるのか Cache Monitoring Authorization Custom Scalar 今日話せなかったこと 様々な開発Tool

Slide 41

Slide 41 text

Thank You! Enjoy GraphQL!