この記事は、gRPC を調べたことを走り書きしたレベルものです。実際の利用経験に基づいた情報でもなければ、しっかり時間をかけて裏付けをとった情報でもないため、誤った理解が含まれている可能性がある点にご注意ください。ツッコミや編集リクエストは歓迎します。
概要
gRPC は、RPC (Remote Procedure Call) を実現するためにGoogleが開発したプロトコルの1つです。Protocol Buffers を使ってデータをシリアライズし、高速な通信を実現できる点が特長です。
gRPCでは、IDL(インターフェース定義言語)を使ってあらかじめAPI仕様を .proto
ファイルとして定義し、そこからサーバー側&クライアント側に必要なソースコードのひな形を生成します。言語に依存しないIDLで先にインタフェースを定義することで、様々なプログラミング言語の実装を生成できるというメリットがあります。
( What is gRPC?より抜粋 )
開発の流れ
実際に gRPC を使って開発する流れは次のようになります。
-
.proto
ファイルの作成helloworld.proto// HelloRequest を受け取って HelloReply を返すメソッドの定義 service Greeter { rpc SayHello (HelloRequest) returns (HelloReply) {} } // HelloRequest のリクエスト定義 message HelloRequest { string name = 1; } // HelloReply のレスポンス定義 message HelloReply { string message = 1; }
-
.proto
をコンパイルして、サーバー&クライアントのひな形コード生成- 各言語での手順は、 http://www.grpc.io/docs/quickstart/
- 例えば、Goの場合は
.pb.go
ファイルに共通インタフェース群が生成される
helloworld.pb.go// Code generated by protoc-gen-go. DO NOT EDIT. // source: helloworld.proto ... package helloworld ... // The request message containing the user's name. type HelloRequest struct { Name string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` } func (m *HelloRequest) Reset() { *m = HelloRequest{} } func (m *HelloRequest) String() string { return proto.CompactTextString(m) } func (*HelloRequest) ProtoMessage() {} func (*HelloRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} } func (m *HelloRequest) GetName() string { if m != nil { return m.Name } return "" } ...
-
2.を使ってサーバー&クライアントを実装する
実装
様々な言語がサポートされており、IDLの価値を高めている気がします。
- C++, Python, Ruby, Objective-C, PHP, C#
- Go
- Java
- Node.js
- JavaScript (ブラウザ)
メリット?
- JSON-RPC と同様に、REST APIよりはURL設計が楽そう
-
.proto
ファイルにAPI仕様を強制的に明文化できる - REST APIやJSON-RPCとは違ってパラメーターをきちんと型付けした状態で扱える安心感
- GoやJavaなどの静的型付け言語と相性がよさそう
- ボイラープレートコードを自動生成でき、品質も上がりそう
- 自動生成が逆に扱いづらいというケースがあるのか現時点では不明
- HTTP/2を活かした高速な双方向ストリーミング通信が可能
デメリット?
- REST APIほどは周辺のエコシステム(デバッグツールやAPIドキュメント生成など)が揃っていなさそう
- データがシリアライズされるのでデバッグはやりづらそう
- バックサーバー間通信には使えるが、フロントエンド/バックエンドサーバー間通信には使えない
- grpc-gateway を使うとREST APIを受け付けるリバースプロキシサーバーを立てられるみたい
- JSON-RPCなどと比べて学習コストは大きそう
追記(2019/01/31)
gRPC-Web の リリース でフロントエンド/バックエンド間での通信にもgRPCが使えるようになりましたが、バックエンドのgRPCサーバーと直接通信できるわけではなく、Envoy のようなgRPC Web対応のプロキシをバックエンド側に立てて通信するようです。
調査できていない
- APIドキュメント系のツール
- テスト、デバッグ周りのツール
- grpc-ecosystem の下に色々ありそう