GraphQLはWeb APIの次のフロンティアか?

次のAPI技術に思いを巡らせ、RESTish JSON over HTTPは大幅に取って代わられることのないほど”十分優れている”かを考える

目次

  1. DXが最重要
  2. RESTは合格点
  3. 次の候補
    a. GraphQL
    b. RPC
    c. カスタムクライアント
  4. 規約とツールで生産性を最大化する

APIコミュニティは長い間、ハイパーメディアを普及させるために多大な労力を費やしました。ハイパーメディアは、人間のようにリンクをたどれるクライアントによってWeb APIの発見性を向上させ、<a>リンクや301リダイレクトといった既存のハイパーテキストやHTTPセマンティクスを再利用することでWeb APIの将来性を高めるものであるとうたわれていました。

しかし、ハイパーメディアは支持を得るのに大変苦労しました。少なくともトラブルの一部は技術的なものでしたが、ハイパーメディアの最大の問題は、役に立たないということではなく、”十分には”役に立たないということでした。ハイパーメディアは、名目上は、現在最もよく見られるRESTish JSON APIに勝る利点があったかもしれませんが、オーバーヘッドの追加を認めさせるほど有用ではありませんでした。

5年にわたって世界のあらゆるAPI会議で強力な普及活動が行われたにもかかわらず、実際にはほとんど採用されていないのですから、ハイパーメディアは次の大きな潮流にはならないと言って差し支えないでしょう。しかし、それでは次に来るのは何かという疑問が湧きます。新しいAPIパラダイムさえ求められているのでしょうか。RESTish JSON over HTTPは非常に実用的で耐久性があることを自ら示しています。ひょっとすると、今後長きにわたり主流となるほど”十分優れている”でしょうか。

DXが最重要

サービスプロバイダとしては、採用したバックエンド技術がユーザに大きな違いをもたらすと考えたくなるかもしれませんが、実際必ずしもそうなるとは限りません。最低限の非攻撃性の要件を満たす限り、それはほぼ当てはまりません(SOAPとOAuth 1は、大きな違いをもたらさない技術の2例)。

統合時の開発者エクスペリエンス(DX)を良好に保つのに使える適当なツールがあれば、ユーザは柔軟になりやすいものです。過度に重かったり、風変わりだったり、嫌がられたりする技術を避ければ、採用している技術よりもドキュメントの質の方がはるかにユーザに注視されるようになるでしょう。

RESTは合格点

Roy Fieldingが発案したRESTの概念はエレガントであり、現在非常に普及していますが、開発者にとってそのパラダイムのAPIにおける実際のメリットがかなり平凡なものであることは、考慮に値します。実際的見地から言えば、RESTの最大の強みは広範な相互運用性(どの言語もHTTPクライアントを有する)とその規約です1。URLは通常、リソースです。リソースには多くの場合、PATCHDELETEといったHTTPメソッドにマップされる標準のCRUD操作が含まれます。状態コードは通常、情報を伝達します。認証やエンコーディングといった一般的に必要とされるAPIの仕組みは時に、AuthorizationContent-Encodingといった標準のHTTPヘッダに組み込まれることもあります。これは全くもって大変便利です。規約のおかげで、開発者はいったん何かを覚えたら、その情報を再利用することで、他の事項がどう動作するかの見当がつけられるのです。

動作 HTTPメソッド URL
作成 POST /customers
置換 PUT /customers/:id
更新 PATCH /customers/:id
削除 DELETE /customers/:id
RESTの規約。URLはリソースであり、CRUDはHTTP動詞にマップされる。

RESTの規約に1つ問題があるとすれば、規約が十分でないということでしょう。上記で”通常”、”多くの場合”、”時に”という表現を使ったのは、これらのやり方は仕様で推奨されているものの守られるとは限らないためです。実世界では、大抵のAPIはRESTishがせいぜいです。例えばStripeでは、リソース更新にPUTではなくPATCHを使うべきですが、歴史的理由でそうはなっておらず、おそらく現時点では変更に値しないでしょう。いずれにしても開発者はドキュメントを読む必要があり、その時、POSTメソッドのユビキタスな使い方があることに気づくのです。

RESTには他の問題もあります。必要なものだけでなく全てが返ってくるため、リソースのペイロードが非常に大きくなることがあるのです。そして多くの場合、クライアントが実際に必要とする種類の情報にうまくマップされておらず、コストの高いN + 1クエリの状況を強いられます。これは、モバイルのような比較的制限のあるネットワークのクライアントにとってはとりわけ問題です。帯域幅と高いレイテンシが相まって、RESTのコストが高くなってしまうからです。

次の候補

業界が今後長期にわたって現状を守る可能性は高そうですが、RESTの非効率性を考えると、新しいものが台頭する余地はあるかもしれません。いくつか見ていきましょう。

GraphQL

GraphQLは現在、支持の高い有力候補です。開発元はFacebookで、GitHubの形式で採用している少なくとも1つの”大規模API”のおかげで、かなりの勢いがあります。しかし、さらに興味深いのは、組織的に利用されていることです。多くの中小企業にとっては、RESTの代わりに採用することで、真っ新なスタートを切りやすいのです。


GraphQLは、複雑な方法で問い合わせ可能なAPIをもたらす。

GraphQLには多くの利点があります。組み込みのイントロスペクションがあるので、開発者は、使おうとしているAPIをツールでナビゲートできます。データは自由な形式で編成することができ、重いリソースにひも付けする必要は必ずしもありません。うまく編成されたグラフは、クライアント要求の処理にちょうど必要なデータセットだけを提供するので、呼び出し数やペイロードサイズの無駄がほとんどありません。あるページをロードするために、何十ではなく単一のAPI要求だけを送信すればよいという状況を想像してみてください。明示性のおかげで、ユーザが何をしようとしているかをよりよく理解できるようになるのですから、これはサービス事業者にとっても素晴らしいことです。

しかし、GraphQLの未来はまだ不確かです。最も注意すべきは、Facebook自体が公開しているAPIにまだGraphQLを採用しておらず、その姿勢が議論を呼んでいることです。また、強みはあるものの、それはRESTish JSONを喜んで使い続けたいという十分多くのオーディエンスが使うには到底力不足という点で、ハイパーメディアと似た位置付けになるかもしれません。

ひょっとすると最も重要な問題点として、GraphQLは私たちの多くが求めている優れた開発者エクスペリエンスを提供できないかもしれません。結局のところ、クライアント側では最低限の型付けと保証しかなされず、ビッグクエリブロブを書き上げることになるのです。そして構造化されているものの、個々の操作はやはりクエリエクスプローラや参考ドキュメントで調べる必要があります。最も似ているのがSQLです。SQLは私たちの多くが日々使っている技術ですが、SQLクエリブロブをメンテナンスするのは大変な作業であるため、大部分の開発者はORMのラッピングに頼っています。きっとGraphQLでも同じことはできるでしょうが、その場合、GraphQLが実際どれほど役に立ったのかと自問する必要があるかもしれません。

RPC

もし大抵のAPIはRESTfulでなくRESTishであり、私たちが実際に使っている規約の大部分は詰まるところURLを一貫した基本的なCRUDにすることであるとすれば、RESTはひょっとすると実際はそれほど受け入れられていないのかもしれないという、非常に有力な見方もできそうです。これは的確な考えかもしれませんが、開発者として私が最優先する価値は、統合の容易さです。APIのイデオロギー的な完全性ははるか3番目の関心事です。

APIの次の大きなパラダイムとして1つ可能性があるのは、APIを単なるRPC(リモートプロシージャコール)のセットにし、gRPCのようなものを使ってユーザが都合の良い時にダウンロードして使えるライブラリを多様な言語で作成することです。gRPCの環境下では、データはHTTP/2上を効率的なProtocol Buffersフォーマットで流れるため、gRPCベースのAPIの転送パフォーマンスはデフォルトで良好となり、ユーザ側や事業者側で手を掛ける必要はありません。

うまく編成されたRPCメソッドのセットであれば、RESTの規約(create_charge()update_customer(id:)delete_subscription(id:)など)と十分張り合い、開発者も使いやすいような規約を提供できるでしょう。


リソースベースの捉え方をやめれば、エンドポイントをユーザ動作によりうまくマップできる。

RESTのリソースベースの捉え方をやめることには、エンドポイントをユーザが実際にやろうとしている動作によりうまくマップできるようになるという利点もあります。例えば、APIにおいて顧客情報を作成する人のほぼ全員が、その顧客に対する課金情報をすぐに作成したい場合、RESTでは個別の2段階(1. POST /customers、2. POST /charges)が必要ですが、その2つの操作を1つにまとめられるのです。

しかし、実世界に変化をもたらすRPCのパワーは、”全員”を納得させられて初めて明らかになるでしょう。もし、AWSやGitHub、Stripeなどが全てgRPCを採用し、新しいAPIとの統合が新しいprotobuf定義をダウンロードしてコードをすぐ書くという簡単な作業だったらと想像してみてください。サポートする全てのインフラ(初期化、ライブラリ、設定など)はすでにあり、使う準備ができているのです。

カスタムクライアント

開発者エクスペリエンスが最重要という考えに戻ると、大規模APIは将来的に、ユーザの関心対象である全ての主流言語で書かれたカスタムライブラリになるかもしれません。その場合、サービスプロバイダにとってメンテナンスのオーバーヘッドはどう見ても大幅に悪化しますが、このようなライブラリは各言語のローカル規約に従って設計され、統合をやりやすくしてくれる可能性があります。


あつらえの革製品作りに役立つ器具。

強い型付けを使えば、APIサーバとの往復通信を行わなくてもコンパイラができるだけ多くのバグを見つけられるようにすることもできるでしょう。例えば、APIキーが提供されない限りはAPIコールを実行できないようにする、新規ユーザの作成にはメールパラメータの提供を必須とする、といったことです。ドキュメントは言語独自のエコシステムの中で提供するか(例:Godoc)、いいIDEがあればコードを書いている時にインラインで表示してもいいでしょう。

この世界では、APIの設計(すなわちREST、GraphQLなどのどれを使うか)は、エンドユーザにとって全く不透明なもので、完全にライブラリメンテナの裁量次第でしょう。関数呼び出しはREST要求に直接変換されるかもしれませんが、ネットワーク効率を最大化するため、ライブラリが各関数呼び出しを特別に作られたGraphQL query(またはミューテーション)にコンパイルすることもできるでしょう。

規約とツールで生産性を最大化する

最後に、生産性向上に役立つ規約のセットを提供してくれた点で、私たちはRESTful APIの功績を無視してはいけません。そのおかげで、新しいAPIを見る際、自分の知っていることを転用できたからです。

GraphQL、RPC、カスタムクライアントはいずれも、REST後の世界に向けてかなり信頼できそうな方法ですが、どれを選択するにしても、規約と広範な一貫性は強力なものであるという、RESTから学んだ教訓を忘れてはいけません。新しいものを採用するなら、技術の断片化によって開発者エクスペリエンスを悪化させることのないよう、できるだけユビキタスにすることを目指すべきです。しかし残念ながら、そうするためには、現実問題として単にRESTを使い続けることになるのかもしれません。

1つ、最終的な強硬意見があります。RESTを宗教のように信奉することは過大評価であり、RESTの知られている利点が支持者の期待したほど十分に実現したことは一度もない、というものです。次に何を選択するにしても、それは柔軟性と効率性を指向しているべきであり、GraphQLは適切な候補と思われます。私たちはバックエンドをGraphQLに移行し、優れた型システムを活用する多数の言語固有ライブラリと組み合わせることで、最初のHTTPコールが発行される前に統合ミスを発見できるようにするべきです。そうすれば、開発者は独自のツールでオートコンプリート(VS IntelliSenseやVimのYouCompleteMe)を使い、成果を上げられるようになります。


  1. RESTが発見とコンテンツネゴシエーション関連の方がもっと優れた機能を提供できるように設計されていることは承知していますが、実際にはそうした機能はどうもあまり使われていないことから、私は通常、規約がRESTの最大の特性であると述べています。