Gin's request validation feature is not working when the request body (JSON) represents an array of objects
Ex:
type item struct {
Field1 string `binding:"required"`
Field2 string `binding:"required"`
}
var items []item
err := c.BindJSON(&items)
To be more clear, the validation logic in gin is expecting the root object to be a struct and hence bails out when an array type gets passed.
Comment From: ycdesu
Yes, this is an expected behavior. From the StructValidator
interface, it says 'If the received type is not a struct, any validation should be skipped and nil must be returned.'.
Comment From: benereich
Even though this might be expected behaviour per interface definition, I was surprised to see binding:"required"
lose its effect without any warnings or complaints at least at runtime.
Comment From: khier996
@ycavatars So, what is best way to validate each object in an array passed in the body?
Comment From: thinkerou
@khier996 yes, closing.
Comment From: rstrlcpy
the issue was closed without answer the last question:
what is best way to validate each object in an array passed in the body?
Could someone answer it?
I define a required struct field as a pointer and later check such fields for nil, but maybe there is not so dirty way?
Comment From: miaojiuchen
+1
Comment From: c1800054work
use
type AutoGenerated []struct {
OrgID string `json:"org_id"`
GroupID string `json:"group_id"`
}
https://mholt.github.io/json-to-go/
Comment From: memochou1993
use dive
Items []Item `json:"mails" binding:"dive"`
Comment From: ns-kliu
use
dive
go Items []Item `json:"mails" binding:"dive"`
Thanks @memochou1993 , it really helps me to validate all objects in an array.
Comment From: fzf404
用
dive
go Items []Item `json:"mails" binding:"dive"`
thank you!
Comment From: noname007
Use UnmarshalJSON
to change the decode behavior
type item struct {
Field1 string `binding:"required"`
Field2 string `binding:"required"`
}
type itemArr []item
func (p *itemArr) UnmarshalJSON(b []byte) error {
//fmt.Println(string(b))
//json.Unmarshal(b, &p)--- wrong
//json.Unmarshal(b, p) --- wrong
var t []item
json.Unmarshal(b, &t)
*p = t
return nil
}
var items itemArr
err := c.BindJSON(&items)