コンテンツにスキップ

カスタムアンマーシャラーのバインド

Ginのデフォルトのバインディングロジックをオーバーライドするには、Go標準ライブラリのencoding.TextUnmarshalerインターフェースを満たす関数を型に定義します。次に、バインドされるフィールドのuri/formタグにparser=encoding.TextUnmarshalerを指定します。

package main
import (
"encoding"
"strings"
"github.com/gin-gonic/gin"
)
type Birthday string
func (b *Birthday) UnmarshalText(text []byte) error {
*b = Birthday(strings.Replace(string(text), "-", "/", -1))
return nil
}
var _ encoding.TextUnmarshaler = (*Birthday)(nil)
func main() {
route := gin.Default()
var request struct {
Birthday Birthday `form:"birthday,parser=encoding.TextUnmarshaler"`
Birthdays []Birthday `form:"birthdays,parser=encoding.TextUnmarshaler" collection_format:"csv"`
BirthdaysDefault []Birthday `form:"birthdaysDef,default=2020-09-01;2020-09-02,parser=encoding.TextUnmarshaler" collection_format:"csv"`
}
route.GET("/test", func(ctx *gin.Context) {
_ = ctx.BindQuery(&request)
ctx.JSON(200, request)
})
_ = route.Run(":8088")
}

テスト方法:

Terminal window
curl 'localhost:8088/test?birthday=2000-01-01&birthdays=2000-01-01,2000-01-02'

結果:

Terminal window
{"Birthday":"2000/01/01","Birthdays":["2000/01/01","2000/01/02"],"BirthdaysDefault":["2020/09/01","2020/09/02"]}

注意: encoding.TextUnmarshalerを実装していない型にparser=encoding.TextUnmarshalerが指定された場合、Ginはそれを無視してデフォルトのバインディングロジックで処理します。

BindUnmarshalerの使用

型がすでにencoding.TextUnmarshalerを実装しているが、Ginでの型のバインド方法を異なる方法でカスタマイズしたい場合(例:返されるエラーメッセージを変更したい場合)、代わりに専用のBindUnmarshalerインターフェースを実装できます。

package main
import (
"strings"
"github.com/gin-gonic/gin"
"github.com/gin-gonic/gin/binding"
)
type Birthday string
func (b *Birthday) UnmarshalParam(param string) error {
*b = Birthday(strings.Replace(param, "-", "/", -1))
return nil
}
var _ binding.BindUnmarshaler = (*Birthday)(nil)
func main() {
route := gin.Default()
var request struct {
Birthday Birthday `form:"birthday"`
Birthdays []Birthday `form:"birthdays" collection_format:"csv"`
BirthdaysDefault []Birthday `form:"birthdaysDef,default=2020-09-01;2020-09-02" collection_format:"csv"`
}
route.GET("/test", func(ctx *gin.Context) {
_ = ctx.BindQuery(&request)
ctx.JSON(200, request)
})
_ = route.Run(":8088")
}

注意: 型がencoding.TextUnmarshalerBindUnmarshalerの両方を実装している場合、バインディングタグでparser=encoding.TextUnmarshalerを指定しない限り、GinはデフォルトでBindUnmarshalerを使用します。