GraphQLは、1回のAPI呼び出しで複数のソースからデータを取得できるAPI用のオープン ソース クエリ言語です。また、既存のデータを使用してクエリを実行するサーバ側のランタイムとしても機能します。GraphQLは、完全なAPIデータ記述を提供しながら、要求されたデータのみをクライアントに渡すことを優先し、APIの拡張と進化を容易にします。

GraphQLについて

GraphQLは、柔軟性と速度を重視し、開発者向けであることを念頭に置いて設計されました。開発者はGraphQLを使用して適切と思われるAPIを構築し、GraphQLの仕様を使用してAPIがクライアントに対して機能することを確認できます。

GraphQLクエリの主な概念の1つは、返されるデータが予測可能であることです。余分なコード文字列ではなく、まさに要求したものが返されます。この宣言型のデータ取得は、帯域幅が制限されているモバイル デバイスで特に役立ちます。さらに、GraphQLを使用するアプリケーションも、サーバではなく、要求/受信されるデータを制御するため、安定していて高速です。また、単一のリクエストで複数のリクエスト項目を一度に返すことができるため、低速のネットワーク接続でも高速で処理できます。

GraphQLのデータ簡素化に基づいて、APIはエンドポイントではなくタイプとフィールドごとに構成されます。これは、すべてのデータに単一のエンドポイントからアクセスでき、アプリケーションは必要なものだけを要求できることを意味します。運用の複雑さが軽減されるため、GraphQLは合理的なAPI接続ソリューションのワークフローに適しています。

簡単な経緯

2012年、Meta(当時はFacebook)は、Facebookモバイル アプリケーション向けに十分に強力なデータ取得APIを必要としていました。Lee Byron氏が率いるFacebookは、特に製品設計者と開発者の観点から、データの取得を簡素化する方法としてGraphQLを開発しました。GraphQLは当初、Facebook社内で使用され、その後2015年に一般公開され、オープン ソース化されました。他の多くのオープン ソース プロジェクトと同じ軌跡をたどり、2019年にGraphQLプロジェクトは、Linux Foundationが主催する独自のGraphQL Foundationに移行されました。

GraphQLは、RESTアーキテクチャの代替として設計されました。標準のREST APIでは、個別のHTTP GETリクエストを介して複数のURLから情報を読み込む必要があります。GraphQL APIを使用すると、すべてのデータが1つのPOSTリクエストで取得されます。RESTとGraphQLはどちらもJSON形式のレスポンスを返しますが、GraphQLはデータの合理化と統合に重点を置いています。

GraphQLの仕組み

GraphQLはきめ細かいデータ リクエストをサポートしているため、クライアントは送信する情報をより詳細に制御できます。クライアントはGraphQLクエリをPOSTリクエストの形式で送信し、サーバはそれに対してJSON形式のレスポンスを返します。GraphQLは特定のアプリケーション アーキテクチャを必要とせず、複数の環境(統合開発環境(IDE)を含む)に導入できます。また、既存のAPI管理ツールや、既存のREST API上で使用できます。

GraphQLの主な用語をいくつか説明します。

  • スキーマ:スキーマは、クライアントがクエリできるデータを示すためにAPI開発者によって作成され、クライアントが要求できるデータを定義するオブジェクト タイプと、オブジェクトの特性を表すフィールドで構成されます。
  • クエリ:クエリはスキーマに基づいて検証され、実行されます。GraphQLはオブジェクト タイプを定義しないでクエリを実行することはできません。
  • リゾルバ:各スキーマ フィールドにアタッチされたリゾルバ関数は、API実行時に値を生成するために呼び出されます。リゾルバは、GraphQLの重要なアーキテクチャ コンポーネントです。

GraphQLのユニークな特長の1つは、レスポンスがクエリの構造(スキーマによって定義されている構造)をミラーリングしていることです。これによってサーバのレスポンスの形式を完全に予測できるため、クライアントの解析が簡素化されます。

設計

GraphQLの階層的な性質はオブジェクト間の関係に従うため、階層型ユーザー インターフェイスでうまく機能します。また、タイプが厳密に指定されるため、各クエリ レベルがタイプと一致し、これらのタイプが一連のフィールドを定義します。この仕組みはSQLに似ており、クエリが完了する前に説明的なエラー メッセージが表示されます。

リゾルバをデータ ソースに接続する

リゾルバは、GraphQLのフィールド、エッジ、ミューテーション、クエリ、サブスクリプションをデータ ソース(およびマイクロサービス)に接続する主要なアーキテクチャ モジュールです。

AWSデータ ソースのリゾルバを構築する方法については、こちらのGraphQLチュートリアルをご覧ください。

取得対象を指定する

GraphQLクエリのユニークな特長の1つが、ミラーリングされたレスポンスです。クエリから返されるデータは、APIリクエストの形式と一致していることがわかっているため、予測することができます。返されるデータの形式がクライアントのクエリに従っていることで、サーバが簡素化されます。

GraphQLのメリット

GraphQLの大きなメリットの1つが、RESTでは利用できない拡張機能を利用できることです。GraphQLのその他のメリットには、以下があります。

信頼できる唯一の情報源を設定

GraphQLスキーマは、GraphQLアプリケーションに信頼できる唯一の情報源を設定し、すべてのデータが記述される主要な場所を1つ提供します。GraphQLスキーマは通常、サーバで定義されますが、クライアントは引き続きスキーマに基づいてクエリし、データを書き込むことができます。

オーバーフェッチが発生しない

RESTアーキテクチャでは、オーバーフェッチがすぐに問題になります。これは、クライアント(フロントエンド)が必要としている要素が1つだけでも、アプリケーション(バックエンド)は各リソースで利用可能なデータを定義して、そのすべてをレスポンスで返すためです。GraphQLの呼び出しは1回のトリップで行われるため、オーバーフェッチが発生することなく、要求されたデータがクライアントに渡されます。

クライアントとサーバの間の通信が向上

GraphQLは、データ タイプが厳密に定義されているため、クライアントとサーバ間の通信がRESTよりも明確です。また、この基盤構造は、複雑なクライアントがGraphQLサーバを呼び出す必要がないことも意味します。詳細と実際のコードを確認するには、GraphQLの公式ページでクライアントとサーバについての説明をご覧ください。

フェデレーションにより拡張可能

設計原則とツールをまとめたAPIフェデレーションによって、限定されたコンテキスト内でサービスを一貫したAPIとしてユーザーに公開できるだけでなく、そのコンテキスト内でサービスを制限なく進化させることができます。GraphQLを使用することで、API全体をフェデレーションし、以前のクエリを壊すことなく進化させる、つまり拡張することができます。この拡張性が、GraphQLが多くの企業で使用されている理由の1つです。

イントロスペクション

GraphQLは本質的にイントロスペクションが可能であるため、GraphQL APIからGraphQLスキーマを取得できます。またクライアントは、利用可能なデータ タイプのリストを要求することもできます。これは、ドキュメントの自動生成や、複数のマイクロサービスのスキーマのテストや取得などに最適です。

GraphQLのデメリット

GraphQLを採用する理由はたくさんありますが、注意すべき欠点もいくつかあります。例えば、すべてをすぐに使えるわけではなく、他の人のAPIを使用するには特別なライブラリが必要です。また全体としてGraphQLは、RESTよりも強力なツールのサポートを必要とします。

RESTと比較したGraphQLのデメリットは、次のとおりです。

学習曲線

REST APIに慣れている開発者は、GraphQLを学習するのにある程度の時間がかかります。また、ワークフローも変わる可能性があります。GraphQLを使用するAPIチームは、保守可能なGraphQLスキーマも作成する必要があります。とはいえ、GraphQLはリクエストとレスポンスの構造が同じであるため、新たに始めるのであれば学びやすく、使いやすいでしょう。

独自のAPI管理戦略

GraphQLには新しいAPI管理戦略が必要な場合がありますが、REST APIは既存のAPI管理モデルに適合する傾向があります。新しいAPI管理戦略を追加すると全体的な費用が増加する可能性があるため、この点を考慮する必要があります。

キャッシュが複雑

通常、リクエストにはHTTPメソッド(GET、POST、PUT、DELETE)を使用するRESTと比べると、GraphQLのキャッシュは複雑です。標準のGraphQLリクエストはPOSTであり、これはHTTPレベルではキャッシュできません。また、エンドポイントが1つであるため、エンドポイントのURLがキャッシュ不能なさまざまなレスポンスを複数生成することも(データの取得ではメリットですが、キャッシュにはデメリットです)、GraphQLのキャッシュを複雑にしています。そのため、サーバ開発者は、それぞれが同じオブジェクト内で動作するにもかかわらず、複数の異なるクエリを作成することになります。とはいえ、多くのGraphQLライブラリでは、すぐに使えるキャッシュ メカニズムを提供しています。