ブラウザにおけるgRPCの状態
gRPC 1.0は2016年8月にリリースされ、それ以来、アプリケーション通信における主要な技術ソリューションの1つとなっています。世界中のスタートアップ、エンタープライズ企業、オープンソースプロジェクトで採用されています。Polyglot環境のサポート、パフォーマンスへの注力、型安全性、開発者の生産性向上は、開発者がアーキテクチャを設計する方法を変革しました。
これまでのところ、そのメリットは主にモバイルアプリ開発者とバックエンド開発者に限定されており、フロントエンド開発者はJSON RESTインターフェースに頼り続ける必要がありました。しかし、gRPC-Webのリリースにより、gRPCはフロントエンド開発者のツールボックスに価値ある追加となることが期待されています。
この記事では、ブラウザでのgRPCの歴史、現在の状況、そして将来についての考察を共有します。
始まり
2016年の夏、GoogleのチームとImprobable1 は、「ブラウザ向けgRPC」とでも呼べるものの実装に独立して着手しました。彼らはすぐに互いの存在に気づき、新しいプロトコルの仕様2 を定義するために協力しました。
gRPC-Web 仕様
HTTP/2 gRPC仕様3 をブラウザで実装することは、現在不可能ですが、それは単にリクエストに対するきめ細かな制御が可能なブラウザAPIが存在しないためです。たとえば、HTTP/2の使用を強制する方法はなく、たとえあったとしても、生のHTTP/2フレームはブラウザからアクセスできません。gRPC-Web仕様は、HTTP/2仕様の視点から開始し、その違いを定義しています。これらには、特に以下のものが含まれます。
- HTTP/1.1とHTTP/2の両方のサポート。
- gRPCメッセージヘッダーの新しいビットで示されるように、リクエスト/レスポンスボディの最後にgRPCトレーラーを送信すること4。
- gRPC-WebリクエストとgRPC HTTP/2レスポンス間の翻訳を行うための必須プロキシ。
技術
基本的な考え方は、ブラウザから通常のHTTPリクエスト(FetchまたはXHRを使用)を送信し、gRPCサーバーの前に小さなプロキシを配置して、リクエストとレスポンスをブラウザが使用できるものに翻訳することです。


2つの実装
GoogleとImprobableのチームは、それぞれ2つの異なるリポジトリ5,6 で仕様を実装しました。実装にはわずかな違いがあり、どちらも仕様に完全に準拠しておらず、長らく互いのプロキシとの互換性がありませんでした7,8。
ImprobableのgRPC-Webクライアント9 はTypeScriptで実装されており、npmでは@improbable-eng/grpc-web10 として利用可能です。また、Goプロキシも利用可能で、既存のGo gRPCサーバーにインポートできるパッケージ11 として、また、任意のgRPCサーバーをgRPC-Webフロントエンドに公開するために使用できるスタンドアロンプロキシ12 として提供されています。
GoogleのgRPC-Webクライアント13 は、Google Closureライブラリ14 をベースにしたJavaScriptで実装されています。npmではgrpc-web15 として利用可能です。当初はNGINX拡張機能16 として実装されたプロキシが付属していましたが、その後、v1.4.0以降のすべてのバージョンで利用可能なEnvoyプロキシHTTPフィルター17 に注力しています。
機能セット
gRPC HTTP/2実装はすべて、ユニタリー、サーバーサイド、クライアントサイド、双方向ストリーミングの4つのメソッドタイプをサポートしています。しかし、gRPC-Web仕様は、クライアントサイドまたは双方向ストリーミングのサポートを特に義務付けておらず、WHATWG Streams18 がブラウザで実装された後に実装されることのみを規定しています。
Googleクライアントは、grpcwebtextモードで使用する場合のみ、ユニタリーとサーバーサイドストリーミングをサポートします。grpcwebモードでは、ユニタリーリクエストのみが完全にサポートされます。これら2つのモードは、リクエストとレスポンスでprotobufペイロードをエンコードする異なる方法を指定します。
Improbableクライアントは、ユニタリーとサーバーサイドストリーミングの両方をサポートしており、ブラウザの機能に応じてXHRとFetchを自動的に選択する実装を備えています。
サポートされているさまざまな機能の概要をまとめた表を以下に示します。
| クライアント / 機能 | トランスポート | ユニタリー | サーバーサイドストリーム | クライアントサイド&双方向ストリーミング |
|---|---|---|---|---|
| Improbable | Fetch/XHR ️ | ✔️ | ✔️ | ❌19 |
Google (grpcwebtext) | XHR ️ | ✔️ | ✔️ | ❌ |
Google (grpcweb) | XHR ️ | ✔️ | ❌20 | ❌ |
この表の詳細については、私のGitHub上の互換性テストリポジトリ を参照してください。
互換性テストは、将来的に、さまざまな互換性を強制および文書化するための自動テストフレームワークに発展する可能性があります。
互換性の問題
もちろん、2つの異なるプロキシがあるため、互換性の問題も発生します。幸いなことに、これらの問題は最近解消されたため、どちらのクライアントもどちらのプロキシでも使用できるようになるはずです。
将来
Googleの実装は、2018年10月にバージョン1.0と一般提供を発表し21、将来の目標のロードマップ22 を公開しました。これには以下が含まれます。
- 効率的なJSONライクなメッセージエンコーディング
- Node、Python、Javaなどのインプロセスプロキシ
- 人気のあるフレームワーク(React、Angular、Vue)との統合
- メモリ効率の良いストリーミングのためのFetch APIトランスポート
- 双方向ストリーミングサポート
Googleは、コミュニティにとってどの機能が重要かについてのフィードバックを求めています。これらの機能のいずれかが特に価値があると思われる場合は、アンケート23 に記入してください。
最近の2つのプロジェクト間の話し合いで、新しいユーザーにはGoogleクライアントとEnvoyプロキシを推奨ソリューションとして採用することに合意しました。Improbableクライアントとプロキシは、Google Closureへの依存なしに仕様の代替実装として存続しますが、実験的なものと見なされるべきです。既存ユーザーがGoogleクライアントに移行するための移行ガイドが作成され、両チームは生成されるAPIを統合するために協力しています。
結論
Googleクライアントは、成功に専念するチームによって、着実に新機能と修正が実装され続け、公式gRPCクライアントとなります。ImprobableクライアントのようなFetch APIサポートはありませんが、コミュニティにとって重要な機能である場合は追加されるでしょう。Googleチームとより広範なコミュニティは、gRPCコミュニティ全体に利益をもたらすために、公式クライアントで協力しています。GA発表以来、Google gRPC-Webリポジトリへのコミュニティからの貢献は劇的に増加しました。
2つのプロキシを選択する際、機能に違いはありません。そのため、デプロイメントモデルの問題になります。Envoyは一部のシナリオに適していますが、インプロセスGoプロキシには独自の利点があります。
今日gRPC-Webを使い始める場合は、まずGoogleクライアントを試してください。厳格なAPI互換性保証があり、GmailやGoogle Mapsで使用されている堅牢なGoogle Closureライブラリをベースに構築されています。Fetch APIのメモリ効率、または実験的なWebsocketクライアントサイドおよび双方向ストリーミングが必要な場合は、Improbableクライアントが適しており、Improbableは今後もそれを継続的に使用および保守します。
いずれにせよ、gRPC-WebはWeb開発者にとって優れた選択肢です。洗練されたプロトコルのポータビリティ、パフォーマンス、エンジニアリングをブラウザにもたらし、フロントエンド開発者にとってエキサイティングな時代をマークします!
参考文献
- improbable.io/games/blog/grpc-web-moving-past-restjson-towards-type-safe-web-apis ↩
- github.com/grpc/grpc/blob/master/doc/PROTOCOL-WEB.md ↩
- github.com/grpc/grpc/blob/master/doc/PROTOCOL-HTTP2.md ↩
- github.com/grpc/grpc/blob/master/doc/PROTOCOL-WEB.md#protocol-differences-vs-grpc-over-http2 ↩
- github.com/improbable-eng/grpc-web ↩
- github.com/grpc/grpc-web ↩
- github.com/improbable-eng/grpc-web/issues/162 ↩
- github.com/grpc/grpc-web/issues/91 ↩
- github.com/improbable-eng/grpc-web/tree/master/client/grpc-web ↩
- npmjs.com/package/@improbable-eng/grpc-web ↩
- github.com/improbable-eng/grpc-web/tree/master/go/grpcweb ↩
- github.com/improbable-eng/grpc-web/tree/master/go/grpcwebproxy ↩
- github.com/grpc/grpc-web/tree/master/javascript/net/grpc/web ↩
- developers.google.com/closure ↩
- npmjs.com/package/grpc-web ↩
- github.com/grpc/grpc-web/tree/master/net/grpc/gateway ↩
- envoyproxy.io/docs/envoy/latest/configuration/http/http_filters/grpc_web_filter ↩
- streams.spec.whatwg.org ↩
- Improbableクライアントは、実験的なwebsocketトランスポートを使用して、クライアントサイドおよび双方向ストリーミングをサポートしています。これはgRPC-Web仕様の一部ではなく、本番環境での使用は推奨されません。↩
-
grpcwebはサーバーサイドストリーミングメソッドの呼び出しを許可しますが、ストリームが閉じられるまでデータは返されません。↩ - gRPC-Webが一般提供開始 ↩
- github.com/grpc/grpc-web/blob/master/doc/roadmap.md ↩
- docs.google.com/forms/d/1NjWpyRviohn5jaPntosBHXRXZYkh_Ffi4GxJZFibylM ↩