🐖
今更Protocol Buffers入門
下記の続き
本題
Protocol Buffers(以下、Protobuf)を触ってみます。
-
公式ドキュメント
https://protobuf.dev/ -
公式のCLIを簡単にインストール可能
$ brew install protobuf
$ protoc --version
下記に.proto
ファイルのサンプルを書いてみます。
1・2はフィールド番号と呼ばれ、シリアライズとデシリアライズの際に使用されるのでユニーク値の設定が必要です。
バージョンは2と3があり、syntaxで定義しますが、理由がなければ3が無難です。
3系はフィールドに必須を宣言できず、全てがOptionalです。
是非については議論があったようですが、本題ではないので、ここでは詳しくは触れません。
参考
syntax = "proto3";
message Person {
string name = 1;
int32 age = 2;
}
Goコード生成
ProtobufファイルをGoにコンパイルするには、別途protoc-gen-go
も必要です。
$ go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
packageやoption go_packageを加えると例えば下記にようになります。
syntax = "proto3";
package tutorial;
option go_package = "./gen";
message Person {
string name = 1;
int32 age = 2;
}
timestampなどのWell Known Typesもインポートして使用できます。
# ディレクトリ例
.
└── protocolbuf
└── tuto.proto
$ protoc -I=protocolbuf --go_out=./ protocolbuf/tuto.proto
# 生成後
.
├── gen
│ └── tuto.pb.go
└── protocolbuf
└── tuto.proto
tuto.pb.goが自動生成されているはずです。
公式が言っているProtocol Buffersで向いていないケース
- 数MBを超えるメッセージで使用するとメモリの使用量が上がる
- 同じ内容でもバイナリ表現が違う場合があるので、パース無しで比較したいケースがある
- 他のフォーマットのほうがメッセージの圧縮で有利なるケースがある
- 科学計算
- FortranやIDLを使用
- 標準規格での構築が必要
以上を踏まえて、一般にGoを使用したWebサービスのユースケースでは問題は起きにくいと考えます。
しかし、gRPCを使用する場合はProtobufは必須ですが、(protoファイルは可動性があり、スキーマファーストで構築できるというメリットはあるものの)REST APIで使うには学習コスト高くない?という問題は存在します。
これは別の3rdパーティツールであるBufが解決してくれそうなので、また次回以降で触ってみたいと思います。
以上、ありがとうございました。
Discussion