GraphQL入門

7b41309d419e0ac011d14774067b0be1?s=47 s-ichikawa
January 26, 2019

 GraphQL入門

7b41309d419e0ac011d14774067b0be1?s=128

s-ichikawa

January 26, 2019
Tweet

Transcript

  1. GraphQL入門 PHP Conference Sendai 2019

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

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

    etc... メルカリと仙台
  4. 今日話すこと - GraphQLとは? - Schema と Query - GraphQLは銀の弾丸? -

    Library, Tool & Services - GraphQLの初め方
  5. GraphQLとは?

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

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

  8. SimpleなWeb Service Browser Server html

  9. SPA + Restful API Browser User News Transaction Todo

  10. SPA + Restful API Browser User News Transaction Todo

  11. SPA + Restful API Browser User News Transaction Todo

  12. Multi Client + Restful API Browser User iOS Android News

    Transaction Todo
  13. Restful APIの問題 エンドポイントにまつわる問題 - Round Tripが増える - 対応漏れが発生しやすくなる(セキュリティ系とか) Responseがどのようなデータ構造をしているのか予測が付きづらい -

    https://example.com/user/123 をGETしたときに返されるResponseはどんな データ構造をもっているか分からない Over Fetching - レスポンスの中に使わないデータが含まれている状態 Under Fetching - レスポンス中に必要なデータが含まれていない状態
  14. GraphQL Browser User iOS Android News Transaction Todo

  15. GraphQLはどう課題解決するか - エンドポイントが増えすぎて管理が煩雑に - 単一エンドポイント - Round Tripが多い - Over

    Fetching, Under Fetching - 1つのクエリで複数のリソースを取得できるため、 1回の Round Tripで必要な情報が過不足なく取得可能 - RequestとResponseのデータ構造の乖離 - GraphQLではQueryとResponseの構造が酷似しているの で理解しやすい
  16. GraphQLの強み - Schemaによる恩恵 - Schema first development - Documentなども自動生成がしやすい -

    IDEなどで補助機能が使える - 開発補助ツール等が豊富 - 学習コストが低い - QueryもSchemaも覚えることはそんなに多くない
  17. History

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

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

  21. Workflow

  22. 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
  23. 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
  24. 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
  25. 開発の流れ Schema Design Implements Monitoring Schema Client API Product Workflow

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

  27. Backend実装の流れ 1. Schema設計する 2. 追加・変更されたSchema毎にResolverを書く Resolver? - Queryで要求されたType(型)を解決するもの。 - DBや外部APIをコールするなどしてデータを用意して型を解決して返す

    - Resolverは定義した型毎に作る、この集合がサーバ実装となる - 作り方は使うLibraryに寄る
  28. 1. Schema作る 2. 開発する a. Client側はQuery書く b. Server側はAPI作る 要は…

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

  30. Schema

  31. 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!] }
  32. 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! }
  33. Enum - ステータスやカテゴリなどの定数を 宣言できる - enumキーワードを使用して表現す る - ScalarやObject Typeと同様に

    フィールドの型として設定すること ができる enum ItemStatus { DRAFT ON_SALE TRADING SOLD CANCEL } type Item { id: ID! name: String! status: ItemStatus! }
  34. ArrayにおけるNullableの表現 配列内の値がNull 配列自体がNull [User] OK OK [User!] NG OK [User]!

    OK NG [User!]! NG NG
  35. Operation Type - GraphQL APIとしてリクエスト可能な オペレーションについて宣言する - 宣言できるオペレーションは3種 - query

    - mutation - subscription schema { query: Query mutation: Mutation } type Query { users: [User!] } type Mutation { registoration(name: String!): User }
  36. 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 }
  37. 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] }
  38. 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
  39. Query

  40. GraphQLのクエリ言語 - GraphQL APIを通してデータの取得や登録・更新を行う為の言語 - Operationは大きく別けて3種類がある(ルートOperation型) - Query - Mutation

    - Subscription - 複数のOperationを1度にリクエストすることは出来ない
  41. Query - データを参照するために使用される - queryキーワードを使用して宣言する - 複数のデータを関係性あるなしに関わらず一括で指定することが可能

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

  44. query { user { id name email follower { id

    name email } } } query { user { ...userInfo follower { ...userInfo } } } flagment userInfo on User { user_id: id name email }
  45. Mutation - 更新系のデータ操作を行うために使用される - SQLで言うところのInsert、Update、Delete辺り - 構文はQueryとほとんど同じ

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

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

  49. 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
  50. 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) }
  51. GraphQLは 銀の弾丸か?

  52. GraphQLが抱える課題 - N+1問題 - 情報をまとめて遅延取得する方法などを使わないと容易に N+1問題が発生する - ファイルアップロード - 別途RESTエンドポイント作るという手法が今の所よく聞く

    - モニタリング - 単一エンドポイントかつ基本的に 200が返るためRestful APIの時とはモニタリングの仕方が全く異 なる - Cache - 単一エンドポイントかつ基本的に POSTを使用するためCDNでCacheするのがちょっと面倒 (できなくはない) GraphQLは銀の弾丸ではない。 Restfulの方がやりやすい時はRestfulを使いましょう。
  53. Architecture Design Pattern

  54. Single server + Database

  55. Service1 Service3 Gateway gRPC http Service2 http

  56. Service1 Hybrid Service2 gRPC http

  57. Library, Tools & Services

  58. Server Libraries - JavaScript - GraphQL.js - express-graphql - Apollo-Server

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

    / Objective-C (iOS) - Apollo iOS - GraphQL iOS - Java (Android) - Apollo Android - Nodes - C#, Go, python
  60. 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
  61. Apollo Platform - GraphQLを使用するための 様々なツールやライブラリ、 サービスなどを統合的に提供 している - Node.jsの技術選択が可能で 予算が許されるなら乗っかっ

    ておくと何かと便利になると思 います
  62. その他 - 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
  63. GraphQLの 始め方

  64. まずは触ってみる - 既にあるGraphQL APIを触ってみる - GitHub API v4 - SW

    API - ここから色々探せます http://apis.guru/graphql-apis/ - 作ってみる - 簡単なサンプル - 既存APIをの一部をGraphQLに置き換えてみる
  65. Learning GraphQL - 今の所日本語のGraphQL専門の書籍はない - 英語であればいくつかあるが、個人的にはこ れがおすすめ - Kindle版もあるのですぐ読めます

  66. 役立つリンク - 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
  67. Conclusion

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

  69. Thank You! Enjoy GraphQL!