(翻訳)gRPC-Web is Generally Available

grpc.io の2018年10月23日のブログ記事 gRPC-Web is Generally Available の翻訳です。少し時間が経過しているので、ホットな話題ではありませんが。

gRPC-Web が Generally Available になりました

満を持して gRPC-Web の GA リリースをお知らせします。gRPC-Web は、 Web アプリが gRPC バックエンドサービスと直接やりとりできるようになる JavaScript クライアントライブラリです。仲介のための HTTP サーバーは不要です。「GA」とはつまり、gRPC-Web は Generally Available で、安定版として本番で使用できるようになったということです。

gRPC-Web を使えば、クライアント/サーバー側のデータ型とサービスインターフェースをプロトコルバッファーで定義することによって、真にエンドツーエンドな gRPC アプリケーションを簡単に作ることができます。これは長らく待望された機能でした。それがついに本番使用の準備が整ったと発表できることは、私たちの喜びであります。また、gRPC サービスにアクセスできるということは、Web ベースの gRPC 周辺ツールを作る上で新しくエキサイティングな可能性を切り開くことになります。

基本

gRPC-Web は gRPC と同じように、クライアント(Web)とバックエンド gRPC サービスとの間にプロトコルバッファーを使ってサービスの「契約」を定義します。そのためクライアントは自動生成が可能です。それをするためには、Closure コンパイラや、より広く使われている CommonJS など選択肢があります。この開発プロセスでは、例えばデータを JSON と相互変換するカスタムロジックを作ったり、HTTP ステータスコードで言い争ったり(REST API にはいろんな流儀があります)、コンテントタイプのネゴシエーションを管理したりといった問題に頭を抱える必要がなくなります。

より広いアーキテクチャの観点からは、gRPC-Web はエンドツーエンドの gRCP を可能にします。次の図を見てください。

f:id:fuji_haruka:20190108212039p:plain

(図1 左はgRCP-Web による gRPC、右は REST による gRPC )

左図の gRPC-Web の世界では、クライアントアプリは gRPC バックエンドサーバーと会話するのにプロトコルバッファーを話し、サーバーは他のバックエンドサービスと会話するのにプロトコルバッファーを話します。右図の REST の世界では、Web アプリはバックエンド REST API サーバーと会話するのに HTTP を話し、サーバーは他のバックエンドサービスと会話するのにプロトコルバッファーを話します。

gRPC-Web を使う利点

gRPC-Web はこれから時間をかけてより広範な機能を提供しますが、今日リリースする1.0の機能は次のとおりです。

  • エンドツーエンド gRPC - RPC パイプラインを一貫してプロトコルバッファーで組み立てることができます。クライアントのリクエストが HTTP サーバーに送られ、それから 5 つのバックエンド gRPC サービスと通信するシナリオを想像してみてください。パイプラインを一貫して HTTP で作るつもりなら、HTTP でやりとりするレイヤーを構築するのにじっくり取り組むのは良い機会といえるでしょう。
  • フロントエンドチームとバックエンドチームの緊密な連携 - RPC パイプラインを一貫してプロトコルバッファーで定義すれば、「マイクロサービスチーム」を「クライアントチーム」の隣の部署に置く必要はもうありません。クライアントとバックエンドのやりとりはたった一つ加わった gRPC レイヤーです。
  • クライアントライブラリの簡単な生成 - gRPC-Web を使えば、「外」の世界とやりとりするサーバー、つまりバックエンドスタックをインターネットに接続する膜となるサーバーが、HTTP サーバーではなく gRPC サーバーになります。サービスで使うクライアントライブラリがすべて gRPC ライブラリになりうるということです。RubyPythonJava、また他の 4 言語でクライアントライブラリがお入り用でしょうか? 各言語でいちいち HTTP クライアントを書く必要はもうありません。

gRPC-Web の例

前節では、スケールするアプリケーションを作るための gRPC-Web の高水準な利点を説明しました。では、サンプルコードで実際に慣れ親しんでみましょう。シンプルな TODO アプリです。gRPC-Web では、まず初めにシンプルな todos.proto をこのように定義します:

syntax = "proto3";

package todos;

message Todo {
  string content = 1;
  bool finished = 2;
}

message GetTodoRequest {
  int32 id = 1;
}

service TodoService {
  rpc GetTodoById (GetTodoRequest) returns (Todo);
} 

クライアント側の CommonJS コードはこの .proto の定義から次のコマンドで生成できます:

protoc echo.proto \
  --js_out=import_style=commonjs:./output \
  --grpc-web_out=import_style=commonjs:./output

次に、バックエンド gRPC サービスから TODO リストを取得するには、シンプルにこう書きます:

const {GetTodoRequest} = require('./todos_pb.js');
const {TodoServiceClient} = require('./todos_grpc_web_pb.js');

const todoService = new proto.todos.TodoServiceClient('http://localhost:8080');
const todoId = 1234;

var getTodoRequest = new proto.todos.GetTodoRequest();
getTodoRequest.setId(todoId);

var metadata = {};
var getTodo = todoService.getTodoById(getTodoRequest, metadata, (err, response) => {
  if (err) {
    console.log(err);
  } else {
    const todo = response.todo();
    if (todo == null) {
      console.log(`A TODO with the ID ${todoId} wasn't found`);
    } else {
      console.log(`Fetched TODO with ID ${todoId}: ${todo.content()}`);
    }
  }
});

ひとたびデータ型とサービスインターフェイスを宣言すれば、gRPC-Web はボイラープレートをすべて捨象して、クリーンで人間に優しい API だけを残してくれます(本質的には現在の Node.js の gRPC API と同じ API をクライアントに移動しただけです)。

バックエンドでは、gRPC サーバーは gRPC をサポートしている言語なら何で書いても構いません。Go、JavaC++Ruby、Node.js など、いろいろな選択肢があります。最後のパズルのピースはサービスプロキシです。get-go から、gRPC-Web は Envoy をデフォルトのサービスプロキシとしてサポートしています。 Envoy には組み込みの envoy.grpc_web filter があって、設定で数行ばかりコピーアンドペーストすれば適用できます。

次のステップ

GA になったということは、コアのビルディングブロックがしっかりと定まり、本番の Web アプリケーションで使用する準備が整ったということです。とはいえ、これからまだ gRPC-Web の機能が追加される予定です。コアチームが次にどんな機能を追加する予定でいるのかを知るためには公式ロードマップを確認してください。

gRPC-Web へのコントリビュートに関心がおありでしたら、コミュニティに貢献する仕事がいくつかあります。

  • フロントエンドフレームワークとの統合 - ReactVueAngular といった広く使われているフロントエンドのフレームワークは gRPC-Web の公式サポートが手付かずです。しかし、私たちはこれらのフレームワークがサポートするのを見てみたいと心から願っています。これらのフレームワークと gRPC-Web の統合が、アプリケーションにパフォーマンス面でユーザーにわかるほどの恩恵を届ける乗り物となりうるからです。もしあなたがこれらのフロントエンドフレームワークをサポートするものを作ることに関心があるのでしたら、gRPC.io メーリングリストで教えていただくか、GitHub機能のリクエストを送るか、あるいは下の機能調査フォームで送るなどをしていただけると助かります。
  • 言語固有のプロキシのサポート - GA リリースでは Envoy が gRPC-Web のデフォルトのプロキシです。Envoy は特別なモジュールによってサポートしているからです。Nginx もサポートしています。けれども私たちは、Envoy や Nginx のような特別なプロキシを用意しなくても済むように、特定言語のプロセス内で使えるプロキシが開発されるのを見たいとも心から願っています。そうすれば gRPC-Web を今よりずっと簡単に使えるようになります。

私たちはまた、コミュニティから新機能のリクエストが出てくることも心から歓迎しています。現在、新機能のリクエストを送る最良の方法は、gRPC-Web ロードマップの機能調査フォームに記入することです。フォームに記入するときには、あなたのほしい機能をリストにしてください。また、あなたがその機能の開発に貢献したいかどうかも「I’d like to contribute to」セクションに記入してください。gRPC-Web エンジニアがプロジェクト開発の工程でその情報を必ず心に留めおくでしょう。

最も大切なことですが、アルファ版とベータ版ユーザの皆さんに感謝したいと思います。フィードバックやバグレポート、そしてプルリクエストを開発期間に送ってくださってありがとうございました。私たちはこの推進力を維持し、このプロジェクトが開発者コミュニティに実際に利益をもたらすようになることを力強く希望しています。