Protocol Buffers
Google が開発した効率的なバイナリシリアライゼーションフォーマットで gRPC の標準データ形式
データ形式RPC
Protocol Buffers とは
Protocol Buffers (protobuf) は、Google が 2008 年にオープンソース化した言語中立・プラットフォーム中立のバイナリシリアライゼーションフォーマットである。.proto ファイルでスキーマを定義し、コンパイラ (protoc) が各言語のシリアライゼーション/デシリアライゼーションコードを自動生成する。gRPC のデフォルトデータ形式として広く使われている。
スキーマ定義
syntax = "proto3";
package order;
message Order {
string id = 1; // フィールド番号で識別
string user_id = 2;
repeated Item items = 3; // 配列
OrderStatus status = 4;
google.protobuf.Timestamp created_at = 5;
}
message Item {
string product_id = 1;
int32 quantity = 2;
int64 price_cents = 3; // 金額はセント単位の整数
}
enum OrderStatus {
ORDER_STATUS_UNSPECIFIED = 0;
ORDER_STATUS_PENDING = 1;
ORDER_STATUS_CONFIRMED = 2;
ORDER_STATUS_SHIPPED = 3;
}
// gRPC サービス定義
service OrderService {
rpc GetOrder(GetOrderRequest) returns (Order);
rpc CreateOrder(CreateOrderRequest) returns (Order);
rpc ListOrders(ListOrdersRequest) returns (stream Order); // サーバーストリーミング
}
フィールド番号 (= 1, = 2) はバイナリエンコーディングで使われる識別子だ。フィールド名ではなく番号で識別するため、フィールド名を変更しても後方互換性が保たれる。
JSON との比較
| 観点 | Protocol Buffers | JSON |
|---|---|---|
| データサイズ | 3〜10 倍小さい | 人間が読めるが冗長 |
| パース速度 | 20〜100 倍速い | パースにコストがかかる |
| スキーマ | 必須 (.proto) | 任意 (JSON Schema) |
| 可読性 | バイナリで人間が読めない | テキストで読める |
| 後方互換性 | フィールド番号で保証 | フィールド名に依存 |
| コード生成 | 自動 (protoc) | 手動 or ツール |
| ブラウザ対応 | grpc-web が必要 | ネイティブ対応 |
スキーマの進化 (後方互換性)
Protocol Buffers の最大の強みは、スキーマの安全な進化だ。
// v1: 初期スキーマ
message User {
string id = 1;
string name = 2;
}
// v2: フィールドを追加 (後方互換)
message User {
string id = 1;
string name = 2;
string email = 3; // 新フィールド: 古いクライアントは無視
repeated string tags = 4; // 新フィールド: 古いクライアントは無視
}
ルール:
- フィールドの追加は安全 (古いクライアントは未知のフィールドを無視)
- フィールド番号を再利用しない (削除したフィールドの番号は
reservedで予約) - フィールドの型変更は非互換 (新しいメッセージ型を作る)
マイクロサービスでの活用
Protocol Buffers + gRPC は、マイクロサービス間の通信に最適だ。.proto ファイルがサービス間の契約 (Contract) として機能し、サーバーとクライアントのコードが自動生成される。JSON + REST に比べて、型安全性が高く、通信効率が良い。
現場での応用を知るには関連書籍も役立つ。