Open8
protocol buffers入門

Prorocol Buffersとは
Googleが開発したデータフォーマット。定義したスキーマをシリアライズ&デシリアライズする機能を持つ。
主な利点は3つ
- データをシリアライズすることで、jsonやxmlよりも軽量&高速にデータをやり取りすることができる
- スキーマを.protoファイルで定義し、PythonやGoなど様々言語でやり取りするためのコードを生成することができる
- スキーマに変更があっても問題ないような後方互換性を持つことができる

Tag
シリアライズ化する際の基準となる。以下でいうと1,2,3...のように振られている番号。
message Account {
uint32 id = 1;
string name = 2;
bytes thumbnail = 3;
bool is_verified = 4;
float height = 5;
}

参考
google公式のリポジトリ。型の付け方などの参考

同じファイルで複数メッセージを定義
syntax = "proto3";
message MessageOne {
}
enum EnumOne {
ENUM_ONE_UNSPECIFIED = 0;
}
message MessageTwo {
MessageOne one = 1;
EnumOne two = 2;
}

package
別ファイルの定義を使用
パッケージ
syntax = "proto3";
package my.package;
message MessageSix {
}
利用側
syntax = "proto3";
// 同じディレクトリのpackage.protoを使用
import "package.proto";
message MessageSeven {
my.package.MessageSix six = 1;
}

oneof
どれか一つのパラメータを許容する
.proto
syntax = "proto3";
package example.oneofs;
option go_package = "example.com/m/proto";
message Result {
oneof result {
string message = 1;
uint32 id = 2;
}
}
main.go
func doOneOf(message interface{}) {
switch x := message.(type) {
case *pb.Result_Id:
fmt.Println(message.(*pb.Result_Id).Id)
case *pb.Result_Message:
fmt.Println(message.(*pb.Result_Message).Message)
default:
fmt.Errorf("message had unexpected type: %v", x)
}
}
func main() {
doOneOf(&pb.Result_Id{Id: 42})
doOneOf(&pb.Result_Message{Message: "a message"})
}

reserved
後方互換性を保つための仕組みとしてreservedがある。
以下の場合、3と10から20のタグ、フィールド名としてold_emailとold_phone_numberは使用できない、という制約を設けることができる。将来的な変更があった場合、これらの制約を設けることで互換性の問題を避けることができる。
syntax = "proto3";
message UserProfile {
reserved 3, 10 to 20;
reserved "old_email", "old_phone_number";
string name = 1;
int32 age = 2;
string email = 4;
}
以下のように制約を破ってビルドしてみるとエラーになる。
syntax = "proto3";
package example.enumarations;
option go_package = "example.com/m/proto";
enum EyeColor {
EYE_COLOR_UNSPECIFIED = 0;
EYE_COLOR_GREEN = 1;
EYE_COLOR_BLUE = 2;
EYE_COLOR_BROWN = 3;
}
message Enumuration {
reserved 2;
EyeColor eye_color = 1;
bool is_simple = 2;
}
protoc -Iproto --go_opt=module=example.com/m --go_out=. proto/*.proto
enumurations.proto: Field "is_simple" uses reserved number 2.
make: *** [generate] Error 1

リポジトリ