いろんな言語を少しでいいから触ってみようという、ライトな感じでGo言語を触り始め、
フレームワークは速度に定評のあるGinを使ってみようということでGo/Ginの勉強をしばらくやっていましたが、
APIを作っていた時に、messagepackでシリアライズ・デシリアライズしてリクエストを受けたりレスポンスをしたりしたくなりました。
調べて判明するまでは時間かかりましたけど、わかっちゃうと割とすぐ対応できたのでメモしますよ
Go/GinでAPIを調べてみると、大体は
c.JSON()
type Request struct {
Param1 int `json:"param1"`
Param2 string `json:"para21"`
}
Ginのパッケージを構成するソースコードはgithubで公開されているため、
JSONの受け取りとレスポンスの仕組みの解析にあたり、github上のソースコードを読んでみました。
すると、JSONをはじめとしていろいろなフォーマットに対応できるように下回りがきっちりしている印象を受け、
この中にmessagepackに対応した下回りが紛れているのでは?と思ったんですね。
試しにmessagepackをキーワードにgrepしてみたところ、、、ありました。すでに下回り実装済みです。
ということは、下回りの呼び出し方さえ分かれば、もうmessagepackへの対応は終わったも同然ですね。
gin-gonic/gin/render/msgpack.go
を中心に解析をしたところ、
c.Render(code int, render.MsgPack{Data:response})
import(
"github.com/gin-gonic/gin"
"github.com/gin-gonic/gin/render"
)
func Response(c *gin.Context, code int, res interface{}) {
c.Render(code, render.MsgPack{Data:res})
}
c *gin.Context
にはBindJSONがあるので、messagepackにバインドするインターフェースもあるかと思ったけど残念ながら見当たらず。
ただ、bindingの種別にMsgPackがあるので、バインドするインターフェースMustBindWithにMsgPackとして渡してあげれば解決します。
import(
"github.com/gin-gonic/gin"
"github.com/gin-gonic/gin/binding"
)
func GetRequestParams(c *gin.Context, obj interface{}) {
return c.MustBindWith(obj, binding.MsgPack)
}
func Hoge(c *gin.Context) {
var request requestParams
GetRequestParams(c, &request) // requestにリクエストパラメータがバインドされる
}
これを書いてるときはgo version 1.16の時でしたけど、いずれはこんなことしなくてもmessagepackに簡単に対応するインターフェースが作られるのではと 勝手に思ってます