英文:
How to validate headers and body in Gin-Gonic?
问题
我有一个Gin程序。当有请求到来时,我希望变量data
(类型为ProductCreate
)的所有字段都有值:UserId
(来自请求头)以及Name
、Price
(来自JSON请求体)。我使用了下面的代码,它可以工作:
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
// 将请求头绑定到data
if err := c.ShouldBindHeader(&data); err != nil {
c.JSON(400, err.Error())
return
}
// 将请求体绑定到data
if err := c.ShouldBindJSON(&data); err != nil {
c.JSON(400, err.Error())
return
}
c.JSON(200, data)
})
r.Run(":8080")
}
之后,我想确保这些字段必须提供,所以我将ProductCreate
结构体修改为:
type ProductCreate struct {
UserId int `header:"user-id" binding:"required"`
Name string `json:"name" binding:"required"`
Price int `json:"price" binding:"required"`
}
然后,当我再次测试时,出现了意外的错误:
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
我意识到错误发生在这里:
// 将请求头绑定到data
if err := c.ShouldBindHeader(&data); err != nil {
c.JSON(400, err.Error())
return
}
有没有解决这个问题的方法?
英文:
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?
答案1
得分: 2
你好!以下是翻译好的内容:
你能试试这个吗?
curl --location --request POST 'http://localhost:8080/product' \
--header 'user-id: 20' \
--data-raw '{
"name": "sr"
}'
我尝试了你的代码,它完美地工作了。
{
"UserId": 20,
"name": "sr",
"price": 0
}
Gin版本:github.com/gin-gonic/gin v1.8.1 // indirect
解决方案:
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{}
// 将头部绑定到数据
if err := c.ShouldBindHeader(header); err != nil {
c.JSON(400, err.Error())
return
}
// 将请求体绑定到数据
if err := c.ShouldBindJSON(data); err != nil {
c.JSON(400, err.Error())
return
}
c.JSON(200, data)
})
r.Run(":8080")
}
英文:
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")
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论