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

GraphQL入門

s-ichikawa
January 26, 2019

 GraphQL入門

s-ichikawa

January 26, 2019
Tweet

More Decks by s-ichikawa

Other Decks in Programming

Transcript

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

    https://example.com/user/123 をGETしたときに返されるResponseはどんな データ構造をもっているか分からない Over Fetching - レスポンスの中に使わないデータが含まれている状態 Under Fetching - レスポンス中に必要なデータが含まれていない状態
  2. GraphQLはどう課題解決するか - エンドポイントが増えすぎて管理が煩雑に - 単一エンドポイント - Round Tripが多い - Over

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

    IDEなどで補助機能が使える - 開発補助ツール等が豊富 - 学習コストが低い - QueryもSchemaも覚えることはそんなに多くない
  4. 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へ
  5. 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
  6. 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
  7. 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
  8. 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!] }
  9. 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! }
  10. Enum - ステータスやカテゴリなどの定数を 宣言できる - enumキーワードを使用して表現す る - ScalarやObject Typeと同様に

    フィールドの型として設定すること ができる enum ItemStatus { DRAFT ON_SALE TRADING SOLD CANCEL } type Item { id: ID! name: String! status: ItemStatus! }
  11. Operation Type - GraphQL APIとしてリクエスト可能な オペレーションについて宣言する - 宣言できるオペレーションは3種 - query

    - mutation - subscription schema { query: Query mutation: Mutation } type Query { users: [User!] } type Mutation { registoration(name: String!): User }
  12. 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 }
  13. 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] }
  14. 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
  15. 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
  16. query { user { id name email follower { id

    name email } } } query { user { ...userInfo follower { ...userInfo } } } flagment userInfo on User { user_id: id name email }
  17. 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
  18. 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
  19. 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) }
  20. GraphQLが抱える課題 - N+1問題 - 情報をまとめて遅延取得する方法などを使わないと容易に N+1問題が発生する - ファイルアップロード - 別途RESTエンドポイント作るという手法が今の所よく聞く

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

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

    / Objective-C (iOS) - Apollo iOS - GraphQL iOS - Java (Android) - Apollo Android - Nodes - C#, Go, python
  23. 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
  24. その他 - 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
  25. まずは触ってみる - 既にあるGraphQL APIを触ってみる - GitHub API v4 - SW

    API - ここから色々探せます http://apis.guru/graphql-apis/ - 作ってみる - 簡単なサンプル - 既存APIをの一部をGraphQLに置き換えてみる
  26. 役立つリンク - 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