カスタム構造体タグを使用したフォームデータのバインド
デフォルトでは、Ginはフォームデータのバインドに form 構造体タグを使用します。異なるタグを使用する構造体をバインドする必要がある場合(例えば、変更できない外部の型など)、独自のタグから読み取るカスタムバインディングを作成できます。
これは、form の代わりに url、query、またはその他のカスタム名のタグを使用するサードパーティライブラリと統合する場合に便利です。
package main
import ( "net/http"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin/binding")
const ( customerTag = "url" defaultMemory = 32 << 20)
type customerBinding struct{}
func (customerBinding) Name() string { return "form"}
func (customerBinding) Bind(req *http.Request, obj any) error { if err := req.ParseForm(); err != nil { return err } if err := req.ParseMultipartForm(defaultMemory); err != nil { if err != http.ErrNotMultipart { return err } } if err := binding.MapFormWithTag(obj, req.Form, customerTag); err != nil { return err } return validate(obj)}
func validate(obj any) error { if binding.Validator == nil { return nil } return binding.Validator.ValidateStruct(obj)}
// FormA is an external type that we can't modify its tagtype FormA struct { FieldA string `url:"field_a"`}
func main() { router := gin.Default()
router.GET("/list", func(c *gin.Context) { var urlBinding = customerBinding{} var opt FormA if err := c.MustBindWith(&opt, urlBinding); err != nil { return } c.JSON(http.StatusOK, gin.H{"field_a": opt.FieldA}) })
router.Run(":8080")}テスト
# The custom binding reads from the "url" struct tag instead of "form"curl "http://localhost:8080/list?field_a=hello"# Output: {"field_a":"hello"}
# Missing parameter -- empty stringcurl "http://localhost:8080/list"# Output: {"field_a":""}