- 概要
- サンプルについて
- Protocol Buffers を動作させる上で必要なものをインストール
- protoファイルを作成
- protoファイルからGoのコードを生成
- サンプル
- 参考情報
- おすすめ書籍
概要
少し前に grpc のメモを書いたのですが
ついでなので、Protocol Buffers 単体で使用してシリアライズとデシリアライズのメモです。
Protocol Buffers (protobuf) のページは以下。
サンプルについて
今回もサンプルはついでなので github にアップしてあります。良かったらご参照ください。
Protocol Buffers を動作させる上で必要なものをインストール
Protocol Buffers を Go で動作させるには
- protocol buffers の コンパイラ protoc
- Go のソースを吐き出すジェネレータ
が必要になります。インストールについては上記の grpc のブログ記事で書いていますので参照ください。
で、上の記事を見ながらインストールしてもいいのですが、Protocol Buffersでサンプル書くたびに打つの面倒なので
gistに makefile アップしときました。
Protocol Buffers (protobuf) と Go のプログラム作るときに使える M…
この makefile 落として
make install-requirements
ってやるとprotocとかprotoc-gen-goのライブラリを落としてきます。
ご利用される場合は、makefile内の protoc のURLとかprotocの生成物の置き場所とかを適時ご自身の環境に調整ください。
私は Crostini (Chromebook の Linux) で作業していますので、ARM64版 (aarch64) のprotoc を使っています。
protoファイルを作成
セットアップが終わったら、次は protoファイルの作成です。
以下のようにしました。
syntax = "proto3"; package main; option go_package = "internal/pb"; message person { string name = 1; int32 age = 2; }
Go で使う場合は option go_package="..."
を付けて、Goのパッケージを指定します。
protoファイルからGoのコードを生成
次に protoファイル からGoのコードを生成します。
上で載せている makefile には、すでにタスクを定義してあります。
$ make protoc mkdir -p internal bin/protoc/bin/protoc -I=proto --go_out=. proto/*.proto mkdir -p doc/proto bin/protoc/bin/protoc --doc_out=html,index.html:./doc/proto proto/*.proto
で生成されます。
生成されたファイルはこんな感じになります。
// Code generated by protoc-gen-go. DO NOT EDIT. // versions: // protoc-gen-go v1.25.0 // protoc v3.13.0 // source: person.proto package pb import ( proto "github.com/golang/protobuf/proto" protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" reflect "reflect" sync "sync" ) const ( // Verify that this generated code is sufficiently up-to-date. _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) // Verify that runtime/protoimpl is sufficiently up-to-date. _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) ) // This is a compile-time assertion that a sufficiently up-to-date version // of the legacy proto package is being used. const _ = proto.ProtoPackageIsVersion4 type Person struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` Age int32 `protobuf:"varint,2,opt,name=age,proto3" json:"age,omitempty"` } func (x *Person) Reset() { *x = Person{} if protoimpl.UnsafeEnabled { mi := &file_person_proto_msgTypes[0] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } func (x *Person) String() string { return protoimpl.X.MessageStringOf(x) } ・・・長いので割愛・・・
サンプル
てことで、シリアライズとデシリアライズのサンプルです。
Protocol Buffers使っている場合は、シリアライズに proto.Marshal()
、デシリアライズに proto.Unmarshal()
を使います。
めっちゃ簡単ですね。
package main import ( "fmt" "log" "protobuftest/internal/pb" "google.golang.org/protobuf/proto" ) func main() { // --------------------------------------------- // Protocol Buffers を使ったシリアライズとデシリアライズのサンプルです. // // REFERENCES: // - https://developers.google.com/protocol-buffers/docs/gotutorial // - https://dev.to/heerthees/protobuf-with-go-4hb // --------------------------------------------- // --------------------------------------------- // シリアライズ // --------------------------------------------- p := &pb.Person{ Name: "hoge", Age: 99, } data, err := proto.Marshal(p) if err != nil { log.Fatal(err) } // - https://devlights.hatenablog.com/entry/2020/08/18/014703 fmt.Printf("[marshal ] [%10T] %[1]v\n", data) // --------------------------------------------- // デシリアライズ // --------------------------------------------- p2 := new(pb.Person) err = proto.Unmarshal(data, p2) if err != nil { log.Fatal(err) } // - https://devlights.hatenablog.com/entry/2020/08/18/014703 fmt.Printf("[unmarshal] [%10T] %[1]v\n", p2) }
実行すると以下のようになります。
$ make run go run cmd/example/main.go [marshal ] [ []uint8] [10 4 104 111 103 101 16 99] [unmarshal] [*pb.Person] name:"hoge" age:99
ちゃんとバイナリ化したものが復元できていますね。
参考情報
おすすめ書籍
自分が読んだGo関連の本で、いい本って感じたものです。
- 作者:Katherine Cox-Buday
- 発売日: 2018/10/26
- メディア: 単行本(ソフトカバー)
- 作者:松尾 愛賀
- 発売日: 2016/04/15
- メディア: 単行本(ソフトカバー)
プログラミング言語Go (ADDISON-WESLEY PROFESSIONAL COMPUTING SERIES)
- 作者:Alan A.A. Donovan,Brian W. Kernighan
- 発売日: 2016/06/20
- メディア: 単行本(ソフトカバー)
過去の記事については、以下のページからご参照下さい。
- いろいろ備忘録日記まとめ
サンプルコードは、以下の場所で公開しています。
- いろいろ備忘録日記サンプルソース置き場