Protcol Buffers とは
プロトコルバッファー (Protocol Buffers、または protobuf) は、Google が開発した、構造化したデータをシリアライズするためのフォーマットです。 同じく Google が開発した gRPC 通信プラットフォームで採用されており、XML や JSON などのテキストベースの API より効率的な通信を行うことができるという特徴を持っています。
- データをコンパクトに表現できるため、通信やパース処理が高速
- 強い型付けを行うことでき、サーバー、クライアントの安全なコーディングが可能
- 定義変更時の互換性を考慮したフォーマット
- OS やプログラミング言語などに非依存
データ構造やサービス形式の定義は、.proto
拡張子を持つ プロトコル定義ファイル (Proto Definition file) で行います。
この .proto
ファイルを protoc
コマンド(プロトコルバッファーコンパイラ)でコンパイルすると、各言語用のソースコードを生成することができます。
protoc
コマンドは各種プログラミング言語用のコードを生成するわけですが、そのためには、protoc コマンド本体 と 各言語用のプラグイン(protoc-gen-go
など)がインストールされている必要があります。
C++ や C#、Kotlin、Python、Ruby などのコード生成は組み込みで対応していますが、Go 言語用のプラグインなどは別途インストールする必要があります。
protoc 本体のインストール
protoc
コマンド (Protocol Buffers Compiler) は、Linux(Ubuntu 系)や macOS ではパッケージマネージャーを使ってインストールしてしまうのが簡単です。
インストールするパッケージの名前は protobuf
や protobuf-compiler
であることに注意してください。
macOS (Homebrew) の場合
$ brew install protobuf # インストール
$ brew upgrade protobuf # バージョン更新
Linux (apt) の場合
$ apt install -y protobuf-compiler
プリビルド版を使う場合
あるいは、各 OS 用のバイナリを GitHub のリリースページ からダウンロードし、protoc
コマンドにパスを通します。
例えば、Windows であれば protoc-3.20.0-win64.zip
などをダウンロードします。
次のように protoc
コマンドを実行できるようになれば OK です。
$ protoc --version
libprotoc 3.20.0
.proto ファイルをコンパイルしてみる
次のような簡単な .proto
ファイルを入力ファイルとして用意します。
C# のコードを生成
例えば、次のように実行すると、C# 用のソースコードを生成することができます。
--csharp_out=<OUT_DIR>
というオプションで、C# ソースコードの出力先ディレクトリを指定しています。
$ mkdir gen
$ protoc --csharp_out=gen proto/person.proto
$ ls gen
Person.cs
Python のコードを生成
Python 用のソースコードを生成したければ、同様に次のようにします。
出力ディレクトリは --python_out=<OUT_DIR>
オプションで指定します。
$ protoc --python_out=gen proto/person.proto
その他の言語のコードを生成
他にも各言語用のソースコードを生成するオプションが用意されており、次のようにヘルプ表示すると標準でサポートしている言語を確認できます。
言語拡張 (protoc-gen-xxx)
protoc
が標準でサポートしてない言語のコードを生成するには、追加のプラグイン(実際はただのコマンド)をインストールする必要があります。
追加でインストールするコマンドは protoc-gen-<言語名>
という名前であり、そのコマンドがシステムに存在していると、protoc
コマンドの --<言語名>_out
というオプションが有効になります。
例: Go 言語用プラグイン (protoc-gen-go)
例えば、Go 言語用のプラグインである protoc-gen-go
をインストールすると、--go_out
オプションが使えるようになります。
Go 言語用のコードを出力する場合は、.proto
ファイル内の option go_package
でパッケージ名を設定しておく必要があります。
次のようにすると、gen
ディレクトリ以下に Go コードが生成されます。
$ protoc --go_out=gen proto/person.proto
.proto
ファイルで指定したパッケージ名に従ってディレクトリ階層ができます。
gen/example.com/myapp/person.pb.go
.proto
ファイル内でパッケージ名を指定するのではなく、protoc
コマンドの --go_opt=M...
オプションで次のように指定することもできます。
$ protoc --go_out=gen \
--go_opt=Mproto/person.proto=example.com/myapp \
proto/person.proto
=
が 2 回出てくるのでちょっと分かりにくいですが、proto/person.proto
ファイルのパッケージ名を example.com/myapp
に設定しています。