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)