I have a Gin program. When a request comes, I want all of the fields of the variable data
(type ProductCreate
) to have values: UserId
(from headers) and Name
, Price
(from JSON body). I used the below code and it works:
package main
import (
"fmt"
"github.com/gin-gonic/gin"
)
type ProductCreate struct {
UserId int `header:"user-id"`
Name string `json:"name"`
Price int `json:"price"`
}
func main() {
r := gin.Default()
r.POST("/product", func(c *gin.Context) {
var data ProductCreate
// bind the headers to data
if err := c.ShouldBindHeader(&data); err != nil {
c.JSON(400, err.Error())
return
}
// bind the body to data
if err := c.ShouldBindJSON(&data); err != nil {
c.JSON(400, err.Error())
return
}
c.JSON(200, data)
})
r.Run(":8080")
}
After that, I wanted to make sure that fields must be provided so I edited the ProductCreate
struct like this:
type ProductCreate struct {
UserId int `header:"user-id" binding:"required"`
Name string `json:"name" binding:"required"`
Price int `json:"price" binding:"required"`
}
Then it raised an unexpected error when I tested it again:
Key: 'ProductCreate.Name' Error:Field validation for 'Name' failed on the 'required' tag\nKey: 'ProductCreate.Price' Error:Field validation for 'Price' failed on the 'required' tag
I realized the error happened at this:
// bind the headers to data
if err := c.ShouldBindHeader(&data); err != nil {
c.JSON(400, err.Error())
return
}
Is there any solution to resolve my problem?
CodePudding user response:
Can you try this?
curl --location --request POST 'http://localhost:8080/product' \
--header 'user-id: 20' \
--data-raw '{
"name": "sr"
}'
I tried your code and it works perfectly.
{
"UserId": 20,
"name": "sr",
"price": 0
}
Gin version: github.com/gin-gonic/gin v1.8.1 // indirect
Soln:
package main
import (
"github.com/gin-gonic/gin"
)
type ProductCreate struct {
Name *string `json:"name" binding:"required"`
Price *int `json:"price" binding:"required"`
}
type Header struct {
UserId *int `header:"user-id" binding:"required"`
}
func main() {
r := gin.Default()
r.POST("/product", func(c *gin.Context) {
data := &ProductCreate{}
header := &Header{}
// bind the headers to data
if err := c.ShouldBindHeader(header); err != nil {
c.JSON(400, err.Error())
return
}
// bind the body to data
if err := c.ShouldBindJSON(data); err != nil {
c.JSON(400, err.Error())
return
}
c.JSON(200, data)
})
r.Run(":8080")
}