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 に比べて、型安全性が高く、通信効率が良い。

現場での応用を知るには関連書籍も役立つ。

関連用語