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 クエリ言語
構造化ログとは - JSON ログの設計と検索性
構造化ログとは、ログを JSON など機械可読な形式で出力し、フィールド単位の検索 / 集計を可能にするロギング手法。非構造化ログとの違い、含めるべきフィールド、失敗パターンを解説
JSON
JavaScript 由来の軽量なデータ交換フォーマットで、Web API のデファクトスタンダード
BFF (Backend for Frontend)
フロントエンドごとに専用のバックエンドを用意し、クライアントに最適化された API を提供するパターン
関連する記事
ディープラーニング本の選び方 - 原理 / 理論 / 実装 / 数学の 4 系統で整理 (2026 年 8 月時点)
ディープラーニング本の選び方を 4 系統 (原理を手で理解する本 / 理論を体系的に学ぶ本 / フレームワーク実装本 / 数学を補う本) に整理。2026 年 8 月時点の定番書を目的別 / レベル別に紹介し、賞味期限の見極め方も解説します。
DevOps 本ガイド - CI/CD とインフラ自動化を学ぶ技術書の選び方
DevOps の文化と原則から CI/CD、IaC、オブザーバビリティまで学べる技術書の選び方と学習順序を紹介します。
データベース本ガイド - SQL から設計まで学べる技術書の選び方
データベースの基礎から設計、パフォーマンスチューニングまで学べる技術書の選び方と学習順序を紹介します。