$30 off During Our Annual Pro Sale. View Details »

GraphQL入門

s-ichikawa
January 26, 2019

 GraphQL入門

s-ichikawa

January 26, 2019
Tweet

More Decks by s-ichikawa

Other Decks in Programming

Transcript

  1. GraphQL入門
    PHP Conference Sendai 2019

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  5. GraphQLとは?

    View Slide

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

    View Slide

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

    View Slide

  8. SimpleなWeb Service
    Browser
    Server
    html

    View Slide

  9. SPA + Restful API
    Browser
    User News Transaction Todo

    View Slide

  10. SPA + Restful API
    Browser
    User News Transaction Todo

    View Slide

  11. SPA + Restful API
    Browser
    User News Transaction Todo

    View Slide

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

    View Slide

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

    View Slide

  14. GraphQL
    Browser
    User
    iOS Android
    News Transaction Todo

    View Slide

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

    View Slide

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

    View Slide

  17. History

    View Slide

  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へ

    View Slide

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

    View Slide

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

    View Slide

  21. Workflow

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  30. Schema

    View Slide

  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!]
    }

    View Slide

  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!
    }

    View Slide

  33. Enum
    - ステータスやカテゴリなどの定数を
    宣言できる
    - enumキーワードを使用して表現す

    - ScalarやObject Typeと同様に
    フィールドの型として設定すること
    ができる
    enum ItemStatus {
    DRAFT
    ON_SALE
    TRADING
    SOLD
    CANCEL
    }
    type Item {
    id: ID!
    name: String!
    status: ItemStatus!
    }

    View Slide

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

    View Slide

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

    View Slide

  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
    }

    View Slide

  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]
    }

    View Slide

  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

    View Slide

  39. Query

    View Slide

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

    View Slide

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

    View Slide

  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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  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

    View Slide

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

    View Slide

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

    View Slide

  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

    View Slide

  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)
    }

    View Slide

  51. GraphQLは
    銀の弾丸か?

    View Slide

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

    View Slide

  53. Architecture
    Design Pattern

    View Slide

  54. Single server + Database

    View Slide

  55. Service1
    Service3
    Gateway
    gRPC
    http
    Service2
    http

    View Slide

  56. Service1
    Hybrid
    Service2
    gRPC
    http

    View Slide

  57. Library, Tools &
    Services

    View Slide

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

    View Slide

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

    View Slide

  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

    View Slide

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

    View Slide

  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

    View Slide

  63. GraphQLの
    始め方

    View Slide

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

    View Slide

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

    View Slide

  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

    View Slide

  67. Conclusion

    View Slide

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

    View Slide

  69. Thank You!
    Enjoy GraphQL!

    View Slide