gRPC
Google が開発した高性能な RPC フレームワークで、Protocol Buffers を用いた効率的なサービス間通信を実現する
gRPC とは
gRPC は、Google が 2015 年にオープンソースとして公開した高性能な RPC (Remote Procedure Call) フレームワークである。HTTP/2 上で Protocol Buffers (protobuf) を使い、言語に依存しない型安全な API 契約をサービス間で共有する。クライアントはローカル関数を呼び出すかのようにリモートサーバーのメソッドを実行できる。
Google 社内では Stubby という RPC フレームワークが 2001 年から使われており、gRPC はその後継としてオープンソース化されたものだ。現在は CNCF (Cloud Native Computing Foundation) のプロジェクトとして管理されている。
REST API との比較
| 観点 | gRPC | REST API |
|---|---|---|
| プロトコル | HTTP/2 | HTTP/1.1 or HTTP/2 |
| データ形式 | Protocol Buffers (バイナリ) | JSON (テキスト) |
| スキーマ | .proto ファイル (必須) | OpenAPI (任意) |
| ストリーミング | 双方向対応 | 非対応 (SSE で片方向) |
| ブラウザ対応 | gRPC-Web 経由 | ネイティブ対応 |
| コード生成 | 自動生成 (多言語) | 手動 or ツール |
| ペイロードサイズ | 小さい (バイナリ) | 大きい (テキスト + キー名) |
| 人間の可読性 | 低い (バイナリ) | 高い (JSON) |
protobuf のバイナリエンコーディングは JSON と比べてペイロードサイズが 3〜10 倍小さく、シリアライズ/デシリアライズも高速だ。マイクロサービス間で秒間数万リクエストを処理する場合、この差は無視できない。
Protocol Buffers の定義
syntax = "proto3";
service OrderService {
rpc CreateOrder (CreateOrderRequest) returns (Order);
rpc GetOrder (GetOrderRequest) returns (Order);
rpc ListOrders (ListOrdersRequest) returns (stream Order); // Server Streaming
}
message CreateOrderRequest {
string customer_id = 1;
repeated OrderItem items = 2;
}
message Order {
string id = 1;
string customer_id = 2;
OrderStatus status = 3;
int64 total_cents = 4; // 金額はセント単位の整数で表現
}
enum OrderStatus {
PENDING = 0;
CONFIRMED = 1;
SHIPPED = 2;
}
.proto ファイルから TypeScript、Go、Java、Python など各言語のクライアント/サーバーコードが自動生成される。API の型安全性がコンパイル時に保証される。
4 つの通信パターン
| パターン | 方向 | 用途 |
|---|---|---|
| Unary | 1 リクエスト → 1 レスポンス | 通常の API 呼び出し (REST と同等) |
| Server Streaming | 1 リクエスト → N レスポンス | ログストリーム、検索結果の逐次返却 |
| Client Streaming | N リクエスト → 1 レスポンス | ファイルアップロード、センサーデータの一括送信 |
| Bidirectional Streaming | N リクエスト ↔ N レスポンス | チャット、リアルタイム同期 |
REST API では実現が難しい双方向ストリーミングが、gRPC ではネイティブにサポートされている。
採用の判断基準
gRPC が適するケース
- バックエンドのマイクロサービス間通信 (高スループット、低レイテンシが求められる)
- 多言語環境 (Go のサービスと TypeScript のサービスが通信する)
- ストリーミングが必要な場面 (リアルタイムデータ、大量データの逐次処理)
- 厳密な API 契約が必要な場面 (型安全性、後方互換性の管理)
REST API が適するケース
- ブラウザとの直接通信 (gRPC-Web は追加のプロキシが必要)
- 外部パートナーへの API 公開 (JSON の方が広く理解されている)
- シンプルな CRUD API (gRPC のセットアップコストが見合わない)
- デバッグのしやすさを重視する場面 (JSON は人間が読める)
実務では、外部向けは REST API、内部のサービス間通信は gRPC というハイブリッド構成が一般的だ。
.proto ファイルの管理
チーム間で .proto ファイルを共有する方法が運用上の重要な課題になる。
- モノレポ: 全サービスの
.protoを 1 つのリポジトリで管理。変更の影響範囲が一目で分かる - 専用リポジトリ:
.protoファイルだけを管理するリポジトリを作り、各サービスが参照する - Buf Registry: Buf (protobuf のツールチェーン) のレジストリで
.protoをパッケージとして配布する
後方互換性の管理も重要だ。フィールド番号の再利用や必須フィールドの追加は破壊的変更になる。buf breaking コマンドで CI に互換性チェックを組み込む。
// gRPC のサービス定義
service OrderService {
rpc CreateOrder (CreateOrderRequest) returns (Order);
rpc GetOrder (GetOrderRequest) returns (Order);
rpc ListOrders (ListOrdersRequest) returns (stream Order);
}
実践的な知識は関連書籍でも得られる。