エンジニアリングチームは、RESTが死んだのか、それともgRPCが他のすべてを過去のものにしたのかといった議論に、いまだに午後の時間を丸ごと費やしている。その議論は本質を見失っている。あなたが選んでいるのは「最高のプロトコル」ではない。「適切な境界(バウンダリ)」なのだ。Kubernetesクラスター内では完璧に機能するプロトコルも、1,000人の外部開発者に開放すれば窒息してしまうだろう。モバイルアプリの貴重な帯域幅を節約するプロトコルも、無制限のパブリッククエリに開放すれば、インフラを破綻させることになる。この決定をテクノロジーの人気投票のように扱うと、チームの現メンバー全員がいなくなった後も残るような、アーキテクチャ上の負債を固めてしまうことになる。

境界の原則

アーキテクチャとはトレードオフの検討であり、勝者を決めることではない。正しい問いは、「どれが一番速いか?」や「どれが最新か?」ではない。「通信の向こう側にいるのは誰か、そして彼らは何を制御しているのか?」である。プロトコルとは境界オブジェクトである。間違ったものを選ぶことは、単に開発を遅らせるだけでなく、その間違いを数年間にわたってシステムに焼き付けてしまうことになる。

パブリックAPI:RESTは退屈なのではなく、責任ある選択なのだ

コンシューマーが面識のない外部開発者である場合、APIは単なるインターフェースではなく、一つの「製品」となる。その開発者は、午前2時にcurlとPostmanのコレクションだけを頼りにデバッグを行っている。最初の呼び出しに成功する前に、カスタムクライアントライブラリをインストールしたりスキーマ言語を学んだりしなければならないとしたら、その時点で彼らを失っている。

RESTがここで生き残っているのは、それがWebそのものだからだ。HTTPメソッド、ステータスコード、そしてJSONは共通言語である。キャッシングは後付けの考えではなく、すでに存在するインフラである。ブラウザ、CDN、エッジキャッシュは、Cache-ControlヘッダーやETagバリデーションをネイティブに理解している。標準的なCDNの背後にREST APIを配置するだけで、キャッシュロジックを一行も書かずに、即座に帯域幅の節約を実現できる。パブリックなトラフィックが予測不能で、クラウドから流出する1ギガバイトごとにコストが発生する場合、これは極めて重要だ。

対照的に、GraphQLをパブリックな境界に導入すると、重い税金(コスト)を課すことになる。パブリックなGraphQLエンドポイントでは、たった一つの不注意な、あるいは悪意のあるクエリがデータベースを破壊するのを防ぐために、クエリコスト分析、深度制限、複雑度スコアリングが必要になる。あなたは単にAPIを提供しているのではない。クエリ実行エンジン、レート制限戦略、そして計算リソースの課金モデルを構築しているのだ。最大手プラットフォームのような運用能力がない限り、パブリックな公開領域に対してそのオーバーヘッドを負うのは無謀である。RESTはデフォルトでガードレールを設定してくれる。各エンドポイントは一つのことだけを行う。コンシューマーは、彼らが思いつくままのデータではなく、あなたが提供するものだけを取得する。

内部サービス:パイプ全体を支配する

組織内部では、議論の内容が変わる。クライアントとサーバーの両方をあなたが制御できるからだ。コールチェーン内のすべてのサービスに対して、テクノロジースタックを指定できる。ここでgRPCの真価が発揮される。

まず、JSONを神聖なものとして扱うのはやめよう。Protocol BuffersはJSONよりも約3倍速くシリアライズできる。フォーマットがバイナリであるため、ペイロードも小さくなる。混雑した内部ネットワークでは、それらのミリ秒とメガバイトが積み重なり、実際のコスト削減やテールレイテンシの低下につながる。さらに重要なのは、Protobufが厳格なコントラクト(契約)を提供してくれることだ。フィールドの型を変更したりメッセージの名前を変更したりした際、問題はコンパイル時に判明する。本番環境の午前3時に、ダウンストリームのサービスがパース例外を投げ始めることで発覚することはない。

gRPCはHTTP/2上で動作するため、ヘッダー圧縮、マルチプレクストリーム、そして真のストリーミングセマンティクスが得られる。サービス間で高スループットなイベントをパイプしたり、リアルタイムの更新をプッシュしたりする場合、サーバーサイドストリーミングや双方向ストリーミングはネイティブな機能であり、リクエスト・レスポンスのフレームワークに無理やり継ぎ接ぎしたロングポーリングのような回避策ではない。

ただし、大きな注意点がある。gRPCをブラウザに直接向けないことだ。ブラウザのネットワーキングモデルは、gRPCが期待するような方法でHTTP/2を話さない。ブラウザをバックエンドと通信させるためだけに、grpc-webやEnvoyのようなプロキシをスタックに継ぎ足す羽目になるだろう。それはバグではなく、境界からのシグナルである。gRPCはファイアウォールの背後、互いに信頼できるサービス間で利用し、そのデバッグの複雑さはスピードに対する代償として受け入れるべきだ。バイナリペイロードは、JSONのようにログファイルでパッと見て内容を確認できるものではない。

複雑なUIとモバイル:GraphQLのニッチな領域

現代のモバイル画面はパッチワークのようになっている。あるビューではユーザープロフィールが必要で、