Slide 1

Slide 1 text

GraphQL入門 PHP Conference Sendai 2019

Slide 2

Slide 2 text

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

Slide 3

Slide 3 text

仙台 お問い合わせ対応 商品監視 etc... 福岡 電話対応 etc... 東京 プロダクトチーム コーポレート etc... メルカリと仙台

Slide 4

Slide 4 text

今日話すこと - GraphQLとは? - Schema と Query - GraphQLは銀の弾丸? - Library, Tool & Services - GraphQLの初め方

Slide 5

Slide 5 text

GraphQLとは?

Slide 6

Slide 6 text

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

Slide 7

Slide 7 text

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

Slide 8

Slide 8 text

SimpleなWeb Service Browser Server html

Slide 9

Slide 9 text

SPA + Restful API Browser User News Transaction Todo

Slide 10

Slide 10 text

SPA + Restful API Browser User News Transaction Todo

Slide 11

Slide 11 text

SPA + Restful API Browser User News Transaction Todo

Slide 12

Slide 12 text

Multi Client + Restful API Browser User iOS Android News Transaction Todo

Slide 13

Slide 13 text

Restful APIの問題 エンドポイントにまつわる問題 - Round Tripが増える - 対応漏れが発生しやすくなる(セキュリティ系とか) Responseがどのようなデータ構造をしているのか予測が付きづらい - https://example.com/user/123 をGETしたときに返されるResponseはどんな データ構造をもっているか分からない Over Fetching - レスポンスの中に使わないデータが含まれている状態 Under Fetching - レスポンス中に必要なデータが含まれていない状態

Slide 14

Slide 14 text

GraphQL Browser User iOS Android News Transaction Todo

Slide 15

Slide 15 text

GraphQLはどう課題解決するか - エンドポイントが増えすぎて管理が煩雑に - 単一エンドポイント - Round Tripが多い - Over Fetching, Under Fetching - 1つのクエリで複数のリソースを取得できるため、 1回の Round Tripで必要な情報が過不足なく取得可能 - RequestとResponseのデータ構造の乖離 - GraphQLではQueryとResponseの構造が酷似しているの で理解しやすい

Slide 16

Slide 16 text

GraphQLの強み - Schemaによる恩恵 - Schema first development - Documentなども自動生成がしやすい - IDEなどで補助機能が使える - 開発補助ツール等が豊富 - 学習コストが低い - QueryもSchemaも覚えることはそんなに多くない

Slide 17

Slide 17 text

History

Slide 18

Slide 18 text

History of GraphQL 2012.xx Facebookで開発が始まる 2015.9 React.js Confでtechnical previewとして公開 2016.9 technical previewをやめて正式に公開 同タイミングでGitHubのAPI v4がGraphQL APIとして公開 2018.11 GraphQL PJの運営がFacebookからGraphQL Foundationへ

Slide 19

Slide 19 text

GraphQL Foundation 幅広い分野の企業がGraphQLプロジェクトの推進のために設立したオープンソース・ ファウンデーション 中立的なGraphQLエコシステムの成長・維持に取り組んでいく ※elementlのロゴ見つからなかった

Slide 20

Slide 20 text

Spec - 誰でも見れる形で公開されている - 2018/7公開された仕様が最新版 https://facebook.github.io/graphql/

Slide 21

Slide 21 text

Workflow

Slide 22

Slide 22 text

query GetUser { user(id: "U12345abcde") { id name } } { "data": { "user": { "id": "U12345abcde", "name": "s-ichikawa" } } } type User { id: ID! name: String! } type Query { user(id: String): User } Schema Query Response GraphQL POST https://example.com/query

Slide 23

Slide 23 text

query GetUser { user(id: "U12345abcde") { id name items (first: 2) { id name price } } } "data": { "user": { "id": "U12345abcde", "name": "s-ichikawa", "items": [ { "id": "I8674665223082153551", "name": "ほうじ茶", "price": 500 }, { "id": "I6129484611666145821", "name": "烏龍茶", "price": 500 } ] } } } Response

Slide 24

Slide 24 text

query GetUser { items { id name price } user(id: "U12345abcde") { id name } } { "errors": [ { "message": "failed to access db", "path": [ "items" ] } ], "data": { "items": null, "user": { "id": "U12345abcde", "name": "s-ichikawa" } } } Error Response

Slide 25

Slide 25 text

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

Slide 26

Slide 26 text

Client実装の流れ 1. Schema設計する 2. 作られたSchemaを元にクライアントで必要なデータを取得したりデータの更新をお こなったりするためQueryを作る 3. Queryを呼び出す処理を書く 4. Responseを使ってクライアントのViewを更新する処理を書く

Slide 27

Slide 27 text

Backend実装の流れ 1. Schema設計する 2. 追加・変更されたSchema毎にResolverを書く Resolver? - Queryで要求されたType(型)を解決するもの。 - DBや外部APIをコールするなどしてデータを用意して型を解決して返す - Resolverは定義した型毎に作る、この集合がサーバ実装となる - 作り方は使うLibraryに寄る

Slide 28

Slide 28 text

1. Schema作る 2. 開発する a. Client側はQuery書く b. Server側はAPI作る 要は…

Slide 29

Slide 29 text

1. Schema作る 2. 開発する a. Client側はQuery書く b. Server側はAPI作る 要は…

Slide 30

Slide 30 text

Schema

Slide 31

Slide 31 text

Object Type - type キーワードを使用して宣言 - { }内にFieldを記載していく - Fieldは 名前: 型名という形で宣言 - Object TypeかScalar Type、 enumが指定可能 - ! はNon Nullable指定 - [ ] はArray - 型やFieldには “(double quote) で ドキュメントが書ける “”” Our Service User “”” type User { id: ID! name: String! follower: [User!] }

Slide 32

Slide 32 text

Scalar Type - 基本となるScalarはたったの5種類 - Int - Float - String - Boolean - ID - 必要に応じてCustom Scalarも作 れる “”” Default Scalarは宣言する必要なし “”” scalar Timestamp type Item { id: ID! name: String! createdAt: Timestamp! updatedAt: TimeStamp! }

Slide 33

Slide 33 text

Enum - ステータスやカテゴリなどの定数を 宣言できる - enumキーワードを使用して表現す る - ScalarやObject Typeと同様に フィールドの型として設定すること ができる enum ItemStatus { DRAFT ON_SALE TRADING SOLD CANCEL } type Item { id: ID! name: String! status: ItemStatus! }

Slide 34

Slide 34 text

ArrayにおけるNullableの表現 配列内の値がNull 配列自体がNull [User] OK OK [User!] NG OK [User]! OK NG [User!]! NG NG

Slide 35

Slide 35 text

Operation Type - GraphQL APIとしてリクエスト可能な オペレーションについて宣言する - 宣言できるオペレーションは3種 - query - mutation - subscription schema { query: Query mutation: Mutation } type Query { users: [User!] } type Mutation { registoration(name: String!): User }

Slide 36

Slide 36 text

Input Type - Query呼び出し時に複雑なデータを 渡したい場合にそれを型として宣言 しておくことができる - 通常のtypeとほぼ同様だがこちらは inputキーワードを使う - 入力値が多い場合などに使うと Schemaの見通しが良くなる - 返り値として設定することはできない mutation { register(name: String!, email: String!, gender: Gender, address: String!): User } ↓ input RegisterInput { name: String! email: String! gender: Gender address: String! } mutation { register(input: RegisterInput): User }

Slide 37

Slide 37 text

Interface - 指定した型に、特定のフィールドを 持つことを約束させる為に使用す る interface Transaction { id: ID! item: Item! } type SellingTransction implements Transaction { id: ID! item: Item! } type CancelTransaction implements Transaction { id: ID! item: Item! reason: String } query { transactions: [Transaction] }

Slide 38

Slide 38 text

Union - 異なる複数の型の内のいずれかの 型 - 全く異なるフィールドを持つ型を1つ の型として表現したい場合に使用 する type News { title: String! content: String! } type Todo { title: String! description: String } type Message { subject: String! body: String } union Notification = News | Todo | Message

Slide 39

Slide 39 text

Query

Slide 40

Slide 40 text

GraphQLのクエリ言語 - GraphQL APIを通してデータの取得や登録・更新を行う為の言語 - Operationは大きく別けて3種類がある(ルートOperation型) - Query - Mutation - Subscription - 複数のOperationを1度にリクエストすることは出来ない

Slide 41

Slide 41 text

Query - データを参照するために使用される - queryキーワードを使用して宣言する - 複数のデータを関係性あるなしに関わらず一括で指定することが可能

Slide 42

Slide 42 text

query GetUser { user(id: "U12345abcde") { id name follower { name } } } { "data": { "user": { "id": "U12345abcde", "name": "ichikawa", "follower": [ {“friend01”}, {“friend02”}, ], } } } type User { id: ID! name: String! follower: [User] } type Query { user(id: String): User } Schema http://example.com/query

Slide 43

Slide 43 text

Query - Programmaticに書くための書式も用意されている - Fragment: 複数のフィールド定義を使いまわしたい場合に効果的 - Alias: 別名をつけることも可能

Slide 44

Slide 44 text

query { user { id name email follower { id name email } } } query { user { ...userInfo follower { ...userInfo } } } flagment userInfo on User { user_id: id name email }

Slide 45

Slide 45 text

Mutation - 更新系のデータ操作を行うために使用される - SQLで言うところのInsert、Update、Delete辺り - 構文はQueryとほとんど同じ

Slide 46

Slide 46 text

mutation Registration { registration (name: "s-ichikawa") { id name } } { "data": { "user": { "id": "U12345abcde", "name": "s-ichikawa" } } } type User { id: ID! name: String! } type Mutation { registration(name: String): User } http://example.com/query

Slide 47

Slide 47 text

Subscription - リアルタイムにデータ参照を行うために使用される - 参照するデータに更新が行われるとWebSocket等を通してクライアントに変更内 容が通知される - GraphQLライブラリが対応していない場合もある

Slide 48

Slide 48 text

Introspection - APIのスキーマ情報を取得するために使用される - 開発ツールなどでオートコンプリートやドキュメント表示を行うためにも使われる。

Slide 49

Slide 49 text

query { __type(name: "User") { name fields { name } } } { "data": { "__type": { "name": "User", "fields": [ { "name": "id" }, { "name": "name" } ] } } } type User { id: ID! name: String! } http://example.com/query

Slide 50

Slide 50 text

Directive - SchemaやQueryに対して付加情 報を与える事ができる - GraphQLの仕様として組み込まれ ているのは - Schemaで使える :@deprecated - Queryで使える:@skip, @include - ライブラリが対応していれば独自の Directiveも作れる “”” in Schema “”” type User { id: ID! name: String! sex: Sex @deprecated } # in Query query myQuery($someTest: Boolean) { experimentalField @skip(if: $someTest) }

Slide 51

Slide 51 text

GraphQLは 銀の弾丸か?

Slide 52

Slide 52 text

GraphQLが抱える課題 - N+1問題 - 情報をまとめて遅延取得する方法などを使わないと容易に N+1問題が発生する - ファイルアップロード - 別途RESTエンドポイント作るという手法が今の所よく聞く - モニタリング - 単一エンドポイントかつ基本的に 200が返るためRestful APIの時とはモニタリングの仕方が全く異 なる - Cache - 単一エンドポイントかつ基本的に POSTを使用するためCDNでCacheするのがちょっと面倒 (できなくはない) GraphQLは銀の弾丸ではない。 Restfulの方がやりやすい時はRestfulを使いましょう。

Slide 53

Slide 53 text

Architecture Design Pattern

Slide 54

Slide 54 text

Single server + Database

Slide 55

Slide 55 text

Service1 Service3 Gateway gRPC http Service2 http

Slide 56

Slide 56 text

Service1 Hybrid Service2 gRPC http

Slide 57

Slide 57 text

Library, Tools & Services

Slide 58

Slide 58 text

Server Libraries - JavaScript - GraphQL.js - express-graphql - Apollo-Server - PHP - graphql-php FWに依存しない形で使うならこれ - Lighthouse Laravelを使っているならこれが活発で良さげ - Java, Go, Ruby, Python, Elixir, Erlang, etc...

Slide 59

Slide 59 text

Client Libraries - JavaScript - Apollo-Client - Relay - Swift / Objective-C (iOS) - Apollo iOS - GraphQL iOS - Java (Android) - Apollo Android - Nodes - C#, Go, python

Slide 60

Slide 60 text

GraphQL IDE - In-browser - GraphiQL https://github.com/skevy/graphiql-app - GraphQL Playground https://github.com/prisma/graphql-playground - Software - Insomnia https://insomnia.rest/graphql/ - Altair GraphQL Client https://github.com/imolorhe/altair

Slide 61

Slide 61 text

Apollo Platform - GraphQLを使用するための 様々なツールやライブラリ、 サービスなどを統合的に提供 している - Node.jsの技術選択が可能で 予算が許されるなら乗っかっ ておくと何かと便利になると思 います

Slide 62

Slide 62 text

その他 - IDE Plugin - for IntelliJ https://github.com/jimkyndemeyer/js-graphql-intellij-plugin - for VSCode https://marketplace.visualstudio.com/items?itemName=Prisma.vscode-graphql - Schema関連 - graphdoc https://github.com/2fd/graphdoc - graphql-doctor https://github.com/cap-collectif/graphql-doctor - Test - graphql-faker https://github.com/APIs-guru/graphql-faker

Slide 63

Slide 63 text

GraphQLの 始め方

Slide 64

Slide 64 text

まずは触ってみる - 既にあるGraphQL APIを触ってみる - GitHub API v4 - SW API - ここから色々探せます http://apis.guru/graphql-apis/ - 作ってみる - 簡単なサンプル - 既存APIをの一部をGraphQLに置き換えてみる

Slide 65

Slide 65 text

Learning GraphQL - 今の所日本語のGraphQL専門の書籍はない - 英語であればいくつかあるが、個人的にはこ れがおすすめ - Kindle版もあるのですぐ読めます

Slide 66

Slide 66 text

役立つリンク - Introduction to GraphQL https://graphql.org/learn/ - 「GraphQL」徹底入門 ─ RESTとの比較、API・フロント双方の実装から学ぶ https://employment.en-japan.com/engineerhub/entry/2018/12/26/103000#GraphQL%E3%81%A8% E3%81%AF%E4%BD%95%E3%81%8B

Slide 67

Slide 67 text

Conclusion

Slide 68

Slide 68 text

Conclusion - GraphQLの仕様はそんなに多くない - 便利なツール類も既に多い - 採用実績はどんどん増えてる - ライブラリに使いたい機能が実装されているかは要確認!

Slide 69

Slide 69 text

Thank You! Enjoy GraphQL!