Gin BindJSON
#Golang #Gin
どのようにバインドするのか知りたかった。
→最終的には標準パッケージのDecodeを呼ぶ。DecodeとUnmarshalの変換仕様はおなじ。
https://godoc.org/github.com/gin-gonic/gin#Context.BindJSON
BindJSON is a shortcut for c.MustBindWith(obj, binding.JSON).
MustBindWithのショートカットだよ
https://godoc.org/github.com/gin-gonic/gin#Context.MustBindWith
MustBindWith binds the passed struct pointer using the specified binding engine. It will abort the request with HTTP 400 if any error occurs. See the binding package.
指定されたバインディングエンジンを使ってバインドするよ
↓
binding/jsonのBindが呼ばれる
gin-gonic/gin@v1.5.0/binding/json.go
内部でdecodeJSONが呼ばれる
code:json.go
func (jsonBinding) Bind(req *http.Request, obj interface{}) error {
if req == nil || req.Body == nil {
return fmt.Errorf("invalid request")
}
return decodeJSON(req.Body, obj)
}
decodeJSONは同じファイルに居る
code:json.go
func decodeJSON(r io.Reader, obj interface{}) error {
decoder := json.NewDecoder(r) // rはreq.Body
if EnableDecoderUseNumber {
decoder.UseNumber()
}
if EnableDecoderDisallowUnknownFields {
decoder.DisallowUnknownFields()
}
if err := decoder.Decode(obj); err != nil {
return err
}
return validate(obj)
}
https://golang.org/pkg/encoding/json/#Decoder.Decode
See the documentation for Unmarshal for details about the conversion of JSON into a Go value.
変換についての詳細はUnmarshalのドキュメントを見てね、とある
https://golang.org/pkg/encoding/json/#Unmarshal
詳細な説明あり
今回気になったのは構造体フィールドがスライスのとき、フィールドがnilになるようなJSON値
Exampleで実験
JSONの値がnull、構造体のフィールドがスライスのとき
→フィールドは空スライス(nil)になる
JSONの値が[null](配列にnullが一個)、構造体のフィールドがスライスのとき
→フィールドはゼロ値が一個入ったスライスになる