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

Rails開発者向けGraphQL入門

Sponsored · Your Podcast. Everywhere. Effortlessly. Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.

 Rails開発者向けGraphQL入門

Avatar for yasudatoshiyuki

yasudatoshiyuki

February 19, 2020
Tweet

More Decks by yasudatoshiyuki

Other Decks in Programming

Transcript

  1. ©iCARE Co., Ltd All rights reserved 自己紹介
 2 名前:安田俊之 関わってきた技術

    Ruby on Rails, Vue.js, AngularJS PHP: Symfony, FuelPHP, CakePHP Java: Androidアプリ、Spring Perl: CGI DB: PostgreSQL, MySQL, Oracle, PL/SQL その他: Terraform, Ansible, Chef, Nginx, etc.
  2. ©iCARE Co., Ltd All rights reserved PostgreSQL Rails Javascript GraphQLってなに?


    5 GraphQL query { users { name email } } SQL SELECT name, email FROM users 弊社の場合のフロー(ブラウザからDBへ) GraphQL サーバー
  3. ©iCARE Co., Ltd All rights reserved GraphQLってなに?
 6 無理やり、RESTに問い合わせ言語の概念を付与すると https://some.where/users

    の /users や https://some.where/users/1 の /users/1 の部分が問い合わせ言語になると言えるでしょうか。 パッと見て分かる通り、RESTの仕様では、userのどういう属性を取得できるか は、問い合わせ内容からは不明ですし、どの属性が欲しくて、どの属性がいら ないかの選択もできないことがわかるかと思います。
  4. ©iCARE Co., Ltd All rights reserved どんなメリットを得られるのか?
 8 REST https://some.where/users

    GET GraphQL https://some.where/graphql POST query { users { name email } } ※他のデータへの問い合わせもエン ドポイントは同じ/graphql リクエストの形式
  5. ©iCARE Co., Ltd All rights reserved どんなメリットを得られるのか?
 9 問い合わせを受け取る実装 REST

    app/controllers/users_controller.rb class UsersController def index @users = User.some_scope end end GraphQL app/graphql/types/query_type.rb module Types class QueryType < Types::BaseObject field :users, [UserType], null: true def users @users = User.some_scope end end end ※GraphQL用のコントローラはあるが、全ての 問い合わせで共通のコントローラ
  6. ©iCARE Co., Ltd All rights reserved どんなメリットを得られるのか?
 10 レスポンス(もしくはレスポンス可能なもの)を定義する実装 REST

    app/views/users/index.json.jbuilder json.users @usrs do | c | json.name c.name json.email c.email ... end ↑ 該当のリクエスト専用の定義のため再利用不 可 GraphQL app/graphql/types/user_type.rb module Types class UserType < Types::BaseObject field :name, String field :email, String end end ↑ 該当のリクエスト専用の定義ではないので再 利用可能(ActiveRecordの定義同様)
  7. ©iCARE Co., Ltd All rights reserved どんなメリットを得られるのか?
 11 型定義の再利用 query

    { orders { price datetime user { name email } } } 上記のように異なる構造のクエリの場合でも、 jbuilderの定義と異なりCustomerTypeの定義 はそのまま再利用できる
  8. ©iCARE Co., Ltd All rights reserved どんなメリットを得られるのか?
 12 実際のレスポンス REST

    { "users":[ { "name":"山田太郎", "email":"taro@yamada", } ] } GraphQL { "data":{ "users":[ { "name":"山田太郎", "email":"taro@yamada", } ] } }
  9. ©iCARE Co., Ltd All rights reserved どんなメリットを得られるのか?
 13 1回のリクエストで得られるレスポンス REST

    userに紐づくorders(注文)を取得するときは、 userごとに別途リクエストをする必要がある GraphQL GraphQL側の型定義さえあれば、1回のクエリ で入れ子構造のデータを取得することができる query { usrs { name email orders { price datetime } } } ※N+1問題に気をつける必要がある
  10. ©iCARE Co., Ltd All rights reserved どんなメリットを得られるのか?
 14 まとめ 1.

    エンドポイントが一つ(/graphql)になるので、Webサーバーにエンドポイントを どう作るかについて悩む必要がなくなる 2. データ定義を資産として再利用できる(RESTの場合のjbuilderだと再利用で きない) 3. リクエスト側から入れ子構造でデータを問い合わせることができるため、1回 のリクエストで複雑な構造のデータを柔軟に取得することができる。(ので、 サーバー側に、たくさんエンドポイントを用意する必要がなくなる) 4. GraphiQL(ブラウザインターフェース)でスキーマ(どんなフィールドがある か)の確認および動作確認ができる