プロジェクトに使用する技術スタックの選定は、一筋縄にはいきません。多くの場合、特にGraphQLとRESTful APIのどちらを選ぶかということになると、現状や今後を見据えたAPIデザインアーキテクチャを選択することが重要になります。
APIを構築するとなると、重要な形式として次の4つが挙げられます─SOAP、GRPC、REST、そしてGraphQLです。とは言え、API構築の際にはRESTとGraphQLに絞ることが多い、というのが実情です。というのも、RESTが従来のSOAPやGRPCによるAPI構築の方法を一変させたという経緯があります。
それをさらに上回る選択肢という触れ込みでGraphQLが語られる傾向にあります。現に、多くの開発者が、GraphQLがRESTに取って代わると予想するほど。REST APIを利用した開発の際によくある問題を、GraphQLが効率的に解決してみせる、というシナリオです。
この2つのAPI構築方法は、本質的に全く異なるものです。共通点と言えば、どちらもHTTPリクエストを送信し、その結果を受信します。どちらにも長所と短所がありますが、この記事では、APIの開発とスケーリングの在り方を変革した、この2つの素晴らしい技術についてご説明します。
詳しい解説に進む前に、まずGraphQLとRESTful APIの意味から考えてみましょう。
GraphQLとは
GraphQLは、APIクエリ言語でありながら、既存のデータを使ってクエリに答えるランタイムでもあります。また、複雑なクエリを処理する優れた機能を搭載しています。
GraphQLの主な特徴は、要求された「特定のデータのみ」を受け取ること。これにより、アプリケーションと一緒にAPIを拡張することが容易になります。
GraphQLの魅力として、すべてのデータが1 つのエンドポイントで提供されます。
上の図は、GraphQLアーキテクチャの典型的な仕組みです。クライアントがさまざまなデバイスからリクエストを行い、GraphQLはそのリクエストを処理し、要求されたデータのみを返します。これにより、RESTful APIにおけるオーバーフェッチとアンダーフェッチの問題をきちんと解決しています。
上の例は、GraphQL Playgroundと、1つのエンドポイントでデータをクエリする方法を示したものです。上部はAPIエンドポイント、左側は世界の大陸の名前を要求するクエリ、右側はクエリに対する応答となっています。
GraphQLは、Facebookによって、REST APIを扱うモバイルアプリ開発者を支援することを主な目的として考案されました。2015年にオープンソースバージョンがリリースされて以来、GraphQLはテックビジネス界のビッグネームによる採用を皮切りに、驚異的な成長を遂げています。
GraphQLを利用中のウェブサービス(一例)
ほんの一例になりますが、サーバー上で積極的にGraphQLを使用している企業やアプリケーションをご紹介します。
FacebookはGraphQLを開発し、2012年以来モバイルアプリの実運用に使用しています。数十億ドル規模のSNS企業である同社は、2015年にGraphQL仕様をオープンソース化。多くの環境とあらゆる規模の組織が活用できるようにしました。
GitHub
GitHubもGraphQLの利用を公表しており、GitHub GraphQL APIを利用して統合機能の作成、データの取得、ワークフローの自動化などを行うことができます。GitHub GraphQL APIは、GitHub REST APIよりも正確で柔軟なクエリを実現します。
写真共有サービスの大手であるPinterestもまた、GraphQLを早い段階から採用しています。GraphQLの導入と、10億ドル規模の企業を支えるGraphQL技術の使用方法について、詳しくはこちらの発表をご覧ください。
Intuit、Shopify、Coursera、Airbnbなど、他の多くの10億ドル規模の企業も、GraphQLをアプリケーションの運営に使用しています。そして、今後も、幅広い業界で注目され続けることでしょう。
RESTful APIとは
RESTは「Representational State Transfer」の略で、分散型ハイパーメディアシステムのためのソフトウェアアーキテクチャのスタイルです。サーバー─クライアント間でリソースを交換するための原則と制約を定義しています。
この原則がAPIで実践されている場合、そのAPIのアプリケーションは「RESTful」と呼ばれます。WordPressのREST APIが、その代表的な例です。
APIがRestful APIと呼ばれるために満たさなければならない原則と制約の一部が以下の通りです。
- クライアントとサーバーのデカップリング:クライアント(フロントエンド)とサーバー(バックエンド)が完全に分離され、エンドポイントを通じてのみ通信が可能。
- 統一されたインターフェース:インターフェースに表示されるデータが、すべてのデバイスで同一である。
- ステートレス:サーバーは、現在のリクエストが初めて行われたものかどうかを覚えていない。リクエストのたびに、それを一から処理するのに必要なすべての情報を用意する必要がある。
- キャッシュ可能性:キャッシュとセッションの保存は許可されているものの、エンドユーザーがデータのキャッシュを拒否できる状態でなければならない。
- レイヤードシステムアーキテクチャ:APIは、クライアントによってもサーバーによっても、直接通信しているのか仲介者を介して通信しているのかが分からないように設計する必要がある。
下の図は、基本的なRESTアーキテクチャです。リクエストとレスポンスが通常どのように処理されるかを示しています。
GraphQLの長所
GraphQLの強みを見てみましょう。10億ドル規模のアプリにすらうってつけの技術であることが、よくわかるはずです。
単一のAPIエンドポイントからのデータ取得
GraphQLの最大の利点は、単一のAPIエンドポイントを通じて、あらゆるデータにアクセスできること。
RESTful APIにありがちな問題が、情報にアクセスするためのエンドポイントが多すぎることです。GraphQLでは、エンドポイントは1つだけなので、オブジェクトに関するさまざまな情報の取得のために複数のリクエストを送信する必要はありません。
下の図は、RESTful APIとGraphQLを使ったリソース取得の違いを示した、わかりやすい例です。RESTful APIでは別のリソースにアクセスするために複数のAPIエンドポイントが必要なのに対し、GraphQLサーバーではリソースにアクセスするエンドポイントが1つしかないことが分かります。
オーバーフェッチ、アンダーフェッチの回避
RESTfulなAPIではお馴染みの問題として、オーバーフェッチやアンダーフェッチがあります。これは、固定のデータ構造を返すエンドポイントを叩きデータをダウンロードしたり、期待される対象よりも多いか少ないデータを取得したりする状態です。
オーバーフェッチとは、あるリクエストで必要とされる以上のデータを受け取る、つまり「フェッチ(fetch=取ってくる)」すること。例えば、ホームページにユーザー名を表示するために、テーブル内の全ユーザーの名前を取得する例を考えてみましょう。オーバーフェッチでは、各ユーザーの名前をはじめとして(名前だけでなく)「すべてのデータ」が返されます。
アンダーフェッチは比較的まれですが、特定のエンドポイントから、要求された情報を取得できない状態です。これが発生した時、クライアントは、必要に応じて他の情報にアクセスできるように追加のリクエストを行う必要があります。
GraphQLは、クライアントが要求したリソースを余すことなく正確に取得することで、オーバーフェッチやアンダーフェッチの問題を効率的に解決してくれます。
複雑なシステムとマイクロサービスの効率的な処理
GraphQL は、複数システム統合に伴う複雑さに調和をもたらす代物です。
例えば、モノリシックなバックエンドアプリケーションからマイクロサービスアーキテクチャに移行したいとします。GraphQL API は、さまざまなマイクロサービスを1つのGraphQLスキーマに統合することで、マイクロサービス間の通信処理を支援します。
このスキーマを定義すると、フロントエンドとバックエンドの両方で(スキーマ内のデータがシステム全体で常に同期されることをフロントエンドが認識し)それ以上の変更なしに別々に通信することが可能になります。
高速かつ安全
オーバーフェッチは、クライアントの帯域幅消費量を引き上げ、やがてアプリケーションの遅延を引き起こす可能性があります。RESTful APIのデザインパターンでは、膨大なペイロードから必要な情報を選別するのに時間がかかります。
一方でGraphQLでは、オーバーフェッチやアンダーフェッチを避け、安全で読み取りやすく、予測可能なデータが返されるため、APIリクエストとレスポンスが素早くなります。
RESTの長所
GraphQLの人気はうなぎ上りですが、それでもRESTは最も人気のあるAPI規格の1つです。その理由を覗いてみましょう。
- 学習の容易さ:RESTful APIは、学習と理解が容易です。他のAPIに勝る重要な強みだと言えます。
- シリアライゼーション:RESTには、データをJSONでシリアライズするための柔軟なアプローチとフォーマットが用意されています。
- キャッシュ:REST APIでは、HTTPプロキシサーバーとキャッシュを駆使し、高負荷のタスクを処理することができます。
- 複雑なリクエスト:REST APIでは、リクエストに対してエンドポイントが分けられるため、他のAPIに比べて複雑なリクエストを管理しやすくなります。
- クリーンでシンプル:REST APIはシンプルかつクリーンです。一見してわかりやすいのが特徴です。
- 標準的なHTTPプロシージャ:RESTでは、データの取得とリクエストの実行に、標準的なHTTPプロシージャのコールアウトが使用されます。
- クライアント/サーバー:ビジネスロジックが、UIから切り離されています。そのため、一方を変更しても、もう一方に影響が出ません。
- ステートレス:明確なコンテキストが付加された状態のメッセージが、クライアント─サーバー間で交換されます。
GraphQLの短所
GraphQLとRESTの長所を説明したところで、今度はGraphQLの欠点について考えてみましょう。
- 学習の難しさ:GraphQLはRESTほど簡単に習得できるものではありません。GraphQL APIを構築する上で最も困難なのはスキーマの設計です。これには多くの時間と知識が必要になります。
- ファイルのアップロード:GraphQLには、ネイティブのファイルアップロード機能がありません。Base64エンコーディングを使って対処することができますが、この方法でのエンコードとデコードには時間と費用がかかることがあります。
- ウェブキャッシュ: キャッシュは繰り返し送られるトラフィックの負荷削減に便利で、よく使う情報をサーバーの近くに保つことでリクエスト、レスポンス処理を高速化できます。GraphQLは、HTTPキャッシュ方式をサポートせず、ApolloまたはRelayクライアントのキャッシュ機構に依存しています。
- 小規模なアプリケーションには不向き:GraphQLは、小規模なアプリケーションの構築には最適なAPIアーキテクチャとは言いがたいです。GraphQLの柔軟なクエリが必要ないアプリケーションでは、RESTの使用で事足ります。
- 複雑なクエリ:GraphQLには「クライアントが望むものをそのまま提供」するという特性があるため、これが時に、クエリ伝搬の問題につながることがあります。クライアントがあまりに多くのネスト状態のクエリを出すと、間違ったクエリが送信される可能性があり、サーバーにとって非常に時間のかかる処理になります。そのようなリクエストには、RESTとカスタムエンドポイントを利用するのが賢明です。
RESTの短所
次に、RESTの弱みに目を向けてみましょう。
- 複数のラウンドトリップ:REST APIの最大の問題は、多数のエンドポイントを伴うという性質です。つまり、すべてのリソース取得のために、無数のラウンドトリップが必要になります。
- オーバーフェッチとアンダーフェッチ:オーバーフェッチとアンダーフェッチの問題は、RESTful APISの顕著な弱点です。無駄に大きなペイロードによって、レスポンスに遅れが生じる可能性があります。
- 階層化:REST APIは、URIを参照するリソースをもとに構築されているため、自然に整理されない、または、単純な階層構造でアクセスできないリソースには不向きです。
RESTの代わりにGraphQLを使用することの意味
次に、今後のAPI開発において、RESTful APIではなくGraphQLを検討するメリットについてご説明します。
強い型付けのスキーマ
GraphQLでは、強い型付けが採用されています。クライアントによるサーバーデータへのアクセス方法を取り巻くパラメータの定義には、スキーマ定義言語(SDL)が使用されます。クライアントに公開されるすべてのAPIはSDLで記述し、これがRESTful APIに見られるデータの不整合に関する問題に対処しています。
オーバーフェッチ、アンダーフェッチなし
RESTful APIの弱みとして、クライアントが要求した情報よりも多い、または少ない情報が返ってくる、オーバー/アンダーフェッチの問題があります。GraphQLでは、必要な情報を指定でき、正確に、そして「その特定の情報のみ」を返すことで、この問題を解決しています。
複数のエンドポイント
RESTful APIの最大の問題の1つは、情報にアクセスするためのエンドポイントが多すぎることです。
例えば、特定のユーザーにID番号でアクセスしたいとします。そのとき、/users/1
のようなエンドポイントが表示されます。しかし、そのユーザーの写真にアクセスするには、/users/1/photos
のような別のエンドポイントにリクエストを送信する必要があります。
GraphQLでは、エンドポイントは1つであり、ユーザーに関するさまざまな情報を取得するために複数のリクエストを送信する必要はありません。
GraphQLとRESTの比較
最後に、GraphQLとRESTful APIの大きな違いを探ります。その後、優れたAPI設計の特徴をいくつか取り上げ、それぞれがどのように扱われているかを比較します。
パフォーマンス
GraphQLでは、すべてのリソースへのアクセスに単一のエンドポイントが利用できるため、RESTful APIよりも高速です。RESTful APIは複数のエンドポイントを使用するため、ネットワークの遅延が発生する可能性があります。
クエリの複雑さ
エンドポイントが複数に分かれていないため、GraphQLのクエリは徐々に複雑になっていく可能性があります。一方、RESTful APIのエンドポイントは分離されているため、自ずと単純なクエリになります。
人気とコミュニティ
GraphQLは、今現在成長中のAPIアーキテクチャパターンおよびクエリ言語です。まだ歴史は浅いですが、その普及とリソースの拡大は急速で、独学を好む人向けの情報はすでに豊富にあります。
一方、RESTはすでに盤石のコミュニティを誇り、小規模なマイクロサービスの構築から複雑なソーシャルアプリの作成まで、あらゆる種類の事業で使用されています。
現時点では、GraphQLとRESTの人気対決は引き分けといったところ。どちらの技術も広く採用されており、開発者のコミュニティに事欠きません。
学習曲線
GraphQLの学習には時間がかかります。API開発および一般的なソフトウェアエンジニアリングに関する十分な知識が必要になります。全くの初心者が複雑なアプリケーションを構築するためにGraphQLを十分に理解するのは、かなり困難でしょう。
逆に、RESTは比較的簡単に学び始めることができ、予備知識も少なくて済みます。RESTful APIは、ほとんどの主要なプログラミング言語や一般的なフレームワークに統合されているため、非常にスムーズに学習できるはずです。
まとめ
GraphQLは、RESTがSOAP APIの問題を解決するために導入されたのと同じように、RESTful APIのアーキテクチャパターンの軌跡をたどる新たな技術です。
GraphQLでは、レスポンスが高速であり、すべてのクエリに対して単一のAPIエンドポイントが利用可能です。一貫したデータアクセスを可能にする厳格なスキーマも注目に値します。これらの理由により、数十億ドル規模の企業が早い段階から、GraphQLに切り替え始めているのには納得です。しかし、一方でRESTは、その機能の制限にもかかわらず、いまだに表舞台で強い存在感を維持し続けています。
というわけで、今回は、GraphQLとRESTful APIについて、それぞれの長所と短所、そして、どちらを選ぶか思考する上で重要な違いをご紹介しました。また、RESTful APIの既知の問題(オーバーフェッチ、アンダーフェッチ、複数のエンドポイントなど)、およびGraphQLがその問題をいかにして解決しアプリのパフォーマンスを向上させているのか見てみました。
今後のプロジェクトにGraphQLとRESTのどちらを使用すべきか。これを判断する上で、今回の記事がお役に立てましたら幸いです。あなたは、どちらを選び、どんなものを構築するでしょうか?コメント欄でお聞かせください。
コメントを残す