SYM's Tech Knowledge Index & Creation Records

「INPUT:OUTPUT=1:1以上」を掲げ構築する Tech Knowledge Stack and Index. by SYM@設計者足るため孤軍奮闘する IT Engineer.

GraphQLについてまとめる

GraphQLについてまとめる

概要

目的を一言で表現するならば

  • 1つのエンドポイントでシステムが管理するリソースから欲しい情報のみを柔軟かつ正確に取得できるようにする

特徴

  • サーバから必要なデータを必要な分だけ、過不足なく(指定した物だけを)取得する
  • 1度のリクエストで(関連のある)複数リソースのデータを取得可能
  • 1 EndPoint。Queryで指定

以下、REST API の課題を解消する狙い

  • 過剰なデータ取得(使わない属性も取得する)
  • 過少なデータ取得(ネストした情報を取るには複数エンドポイントから取得要)
  • (拡張時に) End point の追加が必要になる

(GraphQLドキュメントより翻訳)

GraphQLはRESTに代わる、より効率的で強力かつ柔軟な代替手段を提供する新しいAPI標準です。GraphQLは、そのコアで、クライアントがAPIから必要なデータを正確に指定できる宣言型データフェッチを可能にします。固定データ構造を返す複数のエンドポイントの代わりに、GraphQLサーバーは単一のエンドポイントのみを公開し、クライアントが要求したデータで正確に応答します。

REST API vs GraphQL

REST API:リソースベース

  • メリット
    • リソースが容易に分かる
    • シンプルで一貫性のある設計 (URIと情報の操作が対応する)
  • デメリット
    • リソース毎にエンドポイントを提供、固定データ構造を返却
      • クライアントが必要としていないデータも返却
      • 必要なデータを揃えるために複数エンドポイントの結果を組み合わせが必要なケース発生
      • 必要な関連データも一括で返すようにするとレスポンス肥大化
    • 融通が利かないため柔軟に要求に対応不可
      • 無理に対応すれば上記に繋がり、余分にリソースを消費、レスポンス遅延等に繋がりかねない

GraphQL:ユースケースベース(でqueryを定義するのが良いとされている)

  • メリット
    • 少ないリクエストで複数のリソースにアクセス可能
    • 最小限のデータのみを取得
    • 既存のクエリを破壊せずAPIの更新が可能 (要求に柔軟に対応可能)
  • デメリット
    • キャッシュが複雑になる
    • クエリーの自由度の高さ故に負荷予測や対策がし辛い
    • クエリのパース処理の実装コスト&難易度は高いためライブラリ依存になる
    • 画像や動画などの大容量バイナリの扱いが難しい

GraphQLが真価を発揮するケース

間違いなく言えるのは、管理しているデータが網目状に関連を持ち、(ユースケース的に)色々なルートでその関連を辿る必要がある場合

分かりやすい例:

これをREST APIで対応しようとすると

  • APIでまとめて関連データも返そうとするとレスポンス肥大化
  • APIで対象リソースの関連データについてはIDのみ返すようにしても1ユースケースを満たすために複数API実行

となり、RESTの悪い点を踏む

RESTを使った方が良い時(個人の所感)

「GraphQLの方が色んな面で優れているため、RESTよりGraphQLを使った方が良い」とはならないケースはあるはず。

REST APIの優位性は、シンプルさと統一性(HTTPメソッドとリソースに対応するURI)。

GraphQLサーバ と REST API サーバ の利用者目線(利用者≠フロントエンド。単純にAPIを打つ人という位置づけ)で考えた時に、

GraphQL は、必ずクエリを指定し、対象のリソースや欲しい情報を指定しなければならない。つまり、利用者にその負担を強いる(REST API も更新系は概ねリクエストボディで情報を送る必要があるため手間はそこまで変わらないかもしれないが、参照系はそうでもない)。

複数のサービスから、1リソースの情報を取得しようとした時にどちらが扱いやすいかを考えるとREST API に軍配が上がるだろう(GraphQLだと、複数サービスで同じユースケース(とあるリソース情報を取得する)があれば、複数サービスで同じクエリを持つことになる)。

ただ、RESTでは要求に柔軟に対応することも、リソース間の関連が多いようなデータを扱うのは不得意なため

  • リソース間の関連がさほど多くなく
  • あまり変更が入らないようなデータ

は、REST API の方が良いのではないか。DBで管理するマスターデータ、トランザクションデータのうちの、マスターデータにあたるような物は、データ構造次第ではREST APIの方が扱いやすい可能性があると思われる。

Relay Server Specification

GraphQL拡張仕様

  • Relay Node (Globally unique ID)
  • Relay Connection (Edge, Node, cursor based pagination)
  • Relay Mutation

https://relay.dev/docs/guides/graphql-server-specification/

GraphQLが果たす役割

Todo

GraphQL Client & Server

Client

  • サーバへのクエリの実行とレスポンスの確認 Server
  • クエリに基づいてデータを返す
    • イメージ的には、DBからデータを取得する際には SELECT はせず、アプリケーション側でSELECTすることで指定されたものだけを返すイメージ

Client と Server どちらも用意できるのが Apollo

Apollo Server は、REST APIをデータソースとすることもできるため、Apollo Serverをプロキシとし、GraphQLのインターフェースを提供することができる。つまり、段階的移行が可能である。

Apollo ServerとPrismaではじめるGraphQL API開発入門

Apollo なら爆速で GraphQL サーバーと GraphQL クライアントアプリが作れる

N+1問題への対応

GraphQL で N+1 問題を解決する 4 つのアプローチ