GoでMessagePackのコードを生成するパッケージ(msgpackgen)を作りました
MessagePackとは
まず、公式サイトより引用すると...
MessagePackは、効率の良いバイナリ形式のオブジェクト・シリアライズ フォーマットです。JSONの置き換えとして使うことができ、様々なプログラミング言語をまたいでデータを交換することが可能です。しかも、JSONよりも速くてコンパクトです。
また他にも様々なシリアライザがあると思いますが、MessagePackは50以上の言語で利用可能であり導入しやすいのも特徴です。もちろんGoでも使えるパッケージが存在していますが、新しくmsgpackgenをリリースしました。
なぜ作ったのか
これは前段の話がありまして、実は私自身も後続ではありますが、GoでMessagePackのシリアライザを作ってリリースしています(msgpack)。
速いは正義ということで、他ライブラリよりも速く実装できたので私が関与したサービスで使っていたのですが
「ん〜、データをクライアント(フロントエンド)に返すときって、structに詰めた明瞭な型たち(intとかstringとか)を使うだろうし、それって専用のコードある方がより速く処理できるよな〜」
「例えばAPIサーバで、返すべきデータ定義が決まっているものだったら、それを知っているコードのほうが速く処理できるはずだよな〜」
と漠然と思っていました。そこから幾月か経ち、こんな記事を目にしました。
entityからコード自動生成した話 - Money Forward Kessai TECH BLOG
あ、これ使ったら前考えたこと出来るかも...と思い、作り始め出来上がったのがmsgpackgenです。
ベンチマーク
今はこんな感じになっていて、ShamatonGen
とsuffixについているものが今回紹介しているものになります。知っている範囲でGo製のMessagePackシリアライザと公式のProtobufやJsonをいれて比較してみました。今の所、一番速そうです...!
尚、結果が近しいtinylib
というパッケージもCode Generator付きのシリアライザです。実装の際に比較対象にしていましたが、そちらよりも簡単にコード生成できるような仕組みにするのも心がけました。
ということで、ぜひお試しいただきたい...!!
使い方 - コード生成
まずはコード生成していきます。Goにはgo generate
というコード生成を行う仕組みがあり、ファイルに決められたコメントを記載しておくことで、効力を発揮してくれます。例えばmain.goに
//go:generate go run github.com/shamaton/msgpackgen
と記載し、シェルで
go generate
とすると、main.goがあるディレクトリを含め、再帰的に配下のディレクトリまでコード生成可能な構造体(struct)を検出しコード生成を行います。出力ファイルは1ファイルにまとめられ、デフォルトのファイル名はresolver.msgpackgen.go
で生成されます。
使い方 - シリアライズ
シリアライズを有効にするために、アプリケーションの開始段階などで有効にするメソッドを呼んでおきます。例えばmain.goなどで...
func main() {
// 登録 (resolver.msgpackgen.goにある)
RegisterGeneratedResolver()
// http.Serveするなど
service()
}
シリアライズ/デシリアライズはjson
パッケージのようにMarshal
/Unmarshal
が用意されています。importにgithub.com/shamaton/msgpackgen/msgpack
を追加してください。
func service() {
v := RegisteredStruct{}
b, err := msgpack.Marshal(v)
if err != nil {
panic(err)
}
var vv RegisteredStruct
err = msgpack.Unmarshal(b, &vv)
if err != nil {
panic(err)
}
}
もし、resolver.msgpackgen.go
に登録されていないデータが引数に渡された場合はこちらのmsgpackが呼ばれシリアライズされます。
まとめ
msgpackgenを紹介させていただきました。より細かいことはREADMEに書いてありますが、基本は説明したものだけで機能するようになると思います。試していただけると嬉しいです!
ぜひともよろしくお願いします!
Discussion