gin bindJson array of objects

Viewed 2397

I would like to bind a json array of objects like this one :

[
    {
        "id": "someid"
    },
    {
        "id": "anotherid"
    }
]

Here my model

type DeleteByID struct {
    ID string `json:"id" binding:"required"`
}

I use gin to handle the object

var stock []DeleteByID
if err := ctx.ShouldBindJSON(&stock); err != nil {
 return err
}

The problem is that it does not bind/check my object.

2 Answers

You can achieve this by using json.Unmarshal() like this:

var stock []DeleteByID

body, err := ioutil.ReadAll(c.Request.Body)
if err != nil {
    c.AbortWithError(400, err)
    return
}

err = json.Unmarshal(body, &stock)
if err != nil {
    c.AbortWithError(400, err)
    return
}

c.String(200, fmt.Sprintf("%#v", stock))

The alternative is to pass the array as a nested field. When marked with "dive", gin will bind and validate. These ones will cause an error:

{
  "Deletions": [    {
        "id": 13
    },
    {
    }
  ]
}

This is acceptable input:

{
  "Deletions": [
    {
        "id": "someid"
    },
    {
        "id": "anotherid"
    }
  ]
}

Here my model

type DeleteByID struct {
    ID string `json:"id" binding:"required"`
}

type DeletePayload struct {
    Deletions []DeleteByID `binding:"dive"`
}

The dive keyword will ensure that the JSON array is validated as it becomes a slice, map or array.

var stock DeletePayload
if err := ctx.ShouldBindJSON(&stock); err != nil {
 return err
}

See this issue for some more details: https://github.com/gin-gonic/gin/issues/3238

Related