ProtocolBuffers
- 通信や永続化での利用を目的としたシリアライズフォーマット
- Googleによって開発されている
- オープンソースライセンス
- 多数言語(Java, Python, Objective-C, and C++...)に対応している
JSONや、MessagePackの様につかえる...!!
参考
Protocol Buffers | Google Developers
Protocol Buffers - Wikipedia
環境
- macOS High Sierra
- Windows 10
手順
- protoc を入手
- protoファイルを作成
- protoc コマンドで言語ごとに使用するファイルを出力
- 言語ごとにシリアライズ、デシリアライズ時に上記ファイルを使用
1. Protoc を入手
Mac
Homebrew経由で入手
# terminal等
$ brew update # formula を更新
$ brew upgrade # 更新があるパッケージを再ビルドする
$ brew install protobuf # protobufをインストール
$ brew upgrade protobuf # protobufをアップグレード
$ protoc --version
libprotoc 3.6.0
参考
homebrewでprotobufを最新版(3.0.0)にアップグレードする
Win
ここから、protoc-xxx-win32.zip
を入手。
C:\Program Files\
にProtocフォルダを作って上記zipを解答。
環境変数のPathに C:\Program Files\Protoc\protoc-3.4.0-win32\bin
を設定。
# powershell等
> protoc --version
libprotoc 3.6.0
(より良い方法があったら教えてくださいm(__)m)
2. protoファイルを作成
message Person {
required string name = 1;
required int32 id = 2;
optional string email = 3;
enum PhoneType {
MOBILE = 0;
HOME = 1;
WORK = 2;
}
message PhoneNumber {
required string number = 1;
optional PhoneType type = 2 [default = HOME];
}
repeated PhoneNumber phone = 4;
}
上記は公式のサンプルです。
- required/optionalを定義できる
- enumを使うことができる
- messageフィールドで定義した他のmessageを使うことができる(上記では"PhoneNumber")
- repeatedで繰り返し(配列)を定義できる。
message {
TYPE NAME = UNIQUE NUMBER
}
が基本形のようです。
詳しくは、公式をチェックしてください
Language Guide (proto3) | Protocol Buffers | Google Developers
今回は、以下の簡単なexample.protoを使用します。
syntax = "proto3";
package example;
message User {
int32 id = 1;
string name = 2;
}
3. protoc コマンドで言語ごとに使用するファイルを出力
go言語の場合は、
go get -u github.com/golang/protobuf/{proto,protoc-gen-go}
を先に行ってください。 protocコマンドが裏側でprotoc-gen-goを使用しているみたいです。
protocコマンドを使ってファイルを出力します。
protoc --go_out=. -I. example.proto
- example.pb.go
が出来上がっていると思います。
--xx_out= => xxが言語名、=の後ろにアウトプットしたいパス
-I => インプットフォルダのパス
詳しくは、
protoc --help
をご確認下さい。
4. 言語ごとにシリアライズ、デシリアライズ時に上記ファイルを使用
ただ、シリアライズして、デシリアライズするシンプルなサンプルを以下に置いておきます。
フォルダ構成
.
├── main.go
└── protos
└── example.pb.go
package main
import (
"log"
"./protos"
"github.com/golang/protobuf/proto"
)
func main() {
//Serialize
test := &example.User{
Id: 33,
Name: "laughing_cat",
}
buff, err := proto.Marshal(test)
if err != nil {
log.Print("marshal error")
return
}
log.Print("serialize success: ", buff)
// Deserialize
parsedTest := &example.User{}
err = proto.Unmarshal(buff, parsedTest)
if err != nil {
log.Print("deserialize error: ", err)
}
log.Print("deserialized id :", parsedTest.Id)
log.Print("deserialized name: ", parsedTest.Name)
}
上記で、シリアライズ=>デシリアライズ が完了するかと思います。
importの時に、*.pb.goファイルのパスを指定するのをお忘れなく。
間違えや訂正があったら教えて頂けると嬉しいですm(_ _)m。
参考
公式
今さらProtocol Buffersと、手に馴染む道具の話
Protocol BuffersでAPI通信 サーバー編【golang】