GraphQL ロゴGraphQL

GraphQL ベストプラクティス

GraphQL の仕様書は、ネットワーク、認証、ページネーションの処理など、API が直面する重要な課題のいくつかについては意図的に言及していません。これは、GraphQL を使用する場合にこれらの課題に対する解決策がないという意味ではなく、GraphQL の定義からは外れており、単に一般的な慣習であることを意味します。

このセクションの記事は絶対的なものと見なすべきではなく、場合によっては他のアプローチを優先して無視しても構いません。記事の中には、GraphQL サービスの設計と展開に関して Facebook 内で開発された哲学を紹介するものもあれば、HTTP を介したサービスの提供や認証の実行など、一般的な問題を解決するためのより実践的な提案を行うものもあります。

以下は、GraphQL サービスでより一般的なベストプラクティスと意見について簡単に説明しますが、このセクションの各記事では、これらのトピックやその他のトピックについてより詳細に説明します。

HTTP#

GraphQL は通常、サービスの全機能を表す単一のエンドポイントを介して HTTP で提供されます。これは、それぞれが単一のリソースを公開する一連の URL を公開する REST API とは対照的です。GraphQL は一連のリソース URL と一緒に使用することもできますが、GraphiQL などのツールで使用するのが難しくなる可能性があります。

HTTP を介したサービスの提供で詳しく読んでください。

JSON (GZIP 圧縮付き)#

GraphQL サービスは通常、JSON を使用して応答しますが、GraphQL の仕様では必須ではありません。JSON は、ネットワークパフォーマンスの向上を約束する API レイヤーとしては奇妙な選択に見えるかもしれませんが、ほとんどがテキストであるため、GZIP で非常にうまく圧縮されます。

本番環境の GraphQL サービスでは GZIP を有効にし、クライアントにヘッダーを送信することをお勧めします

Accept-Encoding: gzip

JSON は、クライアントと API 開発者にも非常に馴染みがあり、読みやすくデバッグも簡単です。実際、GraphQL の構文は JSON の構文に一部触発されています。

バージョン管理#

他の REST API と同様に GraphQL サービスのバージョン管理を妨げるものはありませんが、GraphQL は GraphQL スキーマの継続的な進化のためのツールを提供することにより、バージョン管理を回避することを強く推奨しています。

ほとんどの API がバージョン管理を行うのはなぜでしょうか?API エンドポイントから返されるデータの制御が制限されている場合、あらゆる変更が破壊的変更と見なされる可能性があり、破壊的変更には新しいバージョンが必要です。API に新しい機能を追加するために新しいバージョンが必要な場合、頻繁にリリースすることと、API の理解度と保守性を維持することの間でトレードオフが発生します。

対照的に、GraphQL は明示的に要求されたデータのみを返すため、破壊的変更を起こすことなく、新しい型とそれらの型の新しいフィールドを介して新しい機能を追加できます。これにより、破壊的変更を常に回避し、バージョンレス API を提供するという一般的な慣習が生まれました。

Null 許容性#

「null」を認識するほとんどの型システムは、共通型とその型のnull 許容バージョンの両方を提供します。デフォルトでは、明示的に宣言されない限り、型に「null」は含まれません。ただし、GraphQL 型システムでは、すべてのフィールドはデフォルトでnull 許容です。これは、データベースや他のサービスによってサポートされるネットワークサービスでは、多くの問題が発生する可能性があるためです。データベースがダウンしたり、非同期アクションが失敗したり、例外がスローされたりする可能性があります。単純なシステム障害に加えて、認証はきめ細かく行うことができ、リクエスト内の個々のフィールドに異なる認証ルールを設定できます。

すべてのフィールドをデフォルトでnull 許容にすることで、これらの理由のいずれかが発生した場合でも、リクエスト全体が失敗するのではなく、そのフィールドだけが「null」を返します。代わりに、GraphQL は、要求された場合、フィールドが「null」を返さないことをクライアントに保証する非 null型のバリアントを提供します。代わりに、エラーが発生した場合、前の親フィールドが代わりに「null」になります。

GraphQL スキーマを設計する際には、発生する可能性のあるすべての問題と、「null」が失敗したフィールドの適切な値であるかどうかを考慮することが重要です。通常は適切ですが、そうでない場合もあります。そのような場合は、非 null 型を使用して保証します。

ページネーション#

GraphQL 型システムでは、一部のフィールドで値のリストを返すことができますが、長い値のリストのページネーションは API 設計者に任されています。ページネーションには、それぞれに長所と短所がある、さまざまな API 設計が可能です。

通常、長いリストを返す可能性のあるフィールドは、「first」と「after」の引数を受け入れて、リストの特定の領域を指定できるようにします。「after」は、リスト内の各値の一意の識別子です。

最終的に、機能豊富なページネーションを備えた API の設計により、「Connections」と呼ばれるベストプラクティスパターンが生まれました。Relay など、GraphQL の一部のクライアントツールは Connections パターンを認識しており、GraphQL API がこのパターンを採用している場合、クライアント側のページネーションのサポートを自動的に提供できます。

ページネーションの記事で詳しく読んでください。

サーバーサイドのバッチ処理とキャッシュ#

GraphQL は、サーバー上でクリーンなコードを記述できるように設計されています。すべての型のすべてのフィールドには、その値を解決するための焦点を絞った単一目的の関数があります。ただし、追加の考慮事項がない場合、単純な GraphQL サービスは非常に「おしゃべり」になったり、データベースから繰り返しデータをロードしたりする可能性があります。

これは一般にバッチ処理手法によって解決されます。Facebook の DataLoader などのツールを使用して、バックエンドからのデータに対する複数のリクエストを短期間に収集し、基盤となるデータベースまたはマイクロサービスへの単一のリクエストでディスパッチします。

続きを読みます →グラフ思考