Protocol Buffers
Google が開発した効率的なバイナリシリアライゼーションフォーマットで gRPC の標準データ形式
Protocol Buffers とは
Protocol Buffers (protobuf) は、Google が 2008 年にオープンソース化した言語中立 / プラットフォーム中立のバイナリシリアライゼーションフォーマットである。.proto ファイルでスキーマを定義し、コンパイラー (protoc) が各言語のシリアライゼーション/デシリアライゼーションコードを自動生成する。gRPC のデフォルトデータ形式として広く使われている。
スキーマ定義
スキーマ定義の例を示す。
syntax = "proto3";
package order;
import "google/protobuf/timestamp.proto";
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) はバイナリエンコーディングで使われる識別子だ。バイナリ形式はフィールド名を持ち回らないため、名前を変えても既存のバイナリデータはそのまま読める。ただし ProtoJSON やテキスト形式ではフィールド名がそのまま直列化されるので、それらの形式でデータを保存 / 交換している場合は、名前の変更が互換性を壊す変更になる。
proto3 の列挙型は先頭に 0 の値を置くことが必須で、その 0 が既定値になる (例の ORDER_STATUS_UNSPECIFIED)。同じように、明示的な presence を持たないスカラーフィールドは、パースし終えた時点で「0 や false が明示的に入っていた」のか「そもそも送られてこなかった」のかを区別できない。false のときだけ挙動を切り替えるフラグや、0 と未指定を分けたい数量では、optional を付けて presence を持たせる。
JSON との比較
JSON との主な違いを以下に比較する。
| 観点 | Protocol Buffers | JSON |
|---|---|---|
| データサイズ | フィールド名を運ばないぶん小さい | 人間が読めるが冗長 |
| パース速度 | スキーマが既知のため速い | パースにコストがかかる |
| スキーマ | 必須 (.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で予約する (名前を予約しないと、ProtoJSON やテキスト形式で書かれた既存データのパースが壊れる) - 型変更は組み合わせ次第で、一律に非互換ではない。
int32uint32int64uint64boolは相互に互換、stringとbytesも中身が妥当な UTF-8 である限り互換だ。逆にsint32sint64は他の整数型と互換にならず、fixed32はsfixed32と、fixed64はsfixed64としか互換にならない。互換な組み合わせに載らない変更をしたいときは、新しいフィールド番号を起こす
マイクロサービスでの活用
Protocol Buffers + gRPC は、マイクロサービス間の通信に最適だ。.proto ファイルがサービス間の契約 (Contract) として機能し、サーバーとクライアントのコードが自動生成される。JSON + REST に比べて、型安全性が高く、通信効率が良い。
現場での応用を知るには関連書籍も役立つ。
この記事は役に立ちましたか?
関連用語
gRPC
Google が開発した高性能な RPC フレームワークで、Protocol Buffers を用いた効率的なサービス間通信を実現する
REST API
HTTP メソッドとリソース指向の URL で設計する Web API のアーキテクチャスタイル
GraphQL
クライアントが必要なデータだけを指定して取得できる API クエリ言語
API バージョニング (詳解)
API の破壊的変更を管理する戦略の詳細な実装パターン
構造化ログとは - JSON ログの設計と検索性
構造化ログとは、ログを JSON など機械可読な形式で出力し、フィールド単位の検索 / 集計を可能にするロギング手法。非構造化ログとの違い、含めるべきフィールド、失敗パターンを解説
JSON
JavaScript 由来の軽量なデータ交換フォーマットで、Web API のデファクトスタンダード
関連する記事
ディープラーニング本の選び方 - 原理 / 理論 / 実装 / 数学の 4 系統で整理 (2026 年 8 月時点)
ディープラーニング本の選び方を 4 系統 (原理を手で理解する本 / 理論を体系的に学ぶ本 / フレームワーク実装本 / 数学を補う本) に整理。2026 年 8 月時点の定番書を目的別 / レベル別に紹介し、賞味期限の見極め方も解説します。
DevOps 本ガイド - CI/CD とインフラ自動化を学ぶ技術書の選び方
DevOps の文化と原則から CI/CD、IaC、オブザーバビリティまで学べる技術書の選び方と学習順序を紹介します。
データベース本ガイド - SQL から設計まで学べる技術書の選び方
データベースの基礎から設計、パフォーマンスチューニングまで学べる技術書の選び方と学習順序を紹介します。