gin
gin copied to clipboard
how to binding param and json
How to reproduce
package main
import (
"github.com/gin-gonic/gin"
)
type UserRequest struct {
Id int `uri:"id"`
Nickname string `json:"nickname"`
Mobile string `json:"mobile"`
Email string `json:"email"`
}
func main() {
g := gin.Default()
g.GET("/user/:id", func(c *gin.Context) {
// how to do?
})
g.Run(":9000")
}
curl -v -X POST \
http://localhost:8080/user/12\
-H 'content-type: application/json' \
-d '{"nickname": "nickname1","mobile": "133232323232","email": "[email protected]"
Bind twice.
g.POST("/user/:id", func(c *gin.Context) {
var u UserRequest
if err := c.ShouldBindUri(&u); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
if err := c.ShouldBindJSON(&u); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
fmt.Printf("id: %d nickname: %s mobile: %s email: %s\n", u.Id, u.Nickname, u.Mobile, u.Email)
c.JSON(http.StatusNoContent, nil)
})
This is the related issue. https://github.com/gin-gonic/gin/issues/1824
Please tell me if there is another good way!
I also want to know if there is another way
Can't you do something like
u.ID = c.Param("id")?
It seems that it is not possible to bind successfully by calling the API once.
Bind twice.
g.POST("/user/:id", func(c *gin.Context) { var u UserRequest if err := c.ShouldBindUri(&u); err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } if err := c.ShouldBindJSON(&u); err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } fmt.Printf("id: %d nickname: %s mobile: %s email: %s\n", u.Id, u.Nickname, u.Mobile, u.Email) c.JSON(http.StatusNoContent, nil) })This is the related issue. #1824
Please tell me if there is another good way!
Only work with non-required fields. Is there anyway with required fields?
type UpdateRequest struct {
ID uint64 `uri:"id" binding:"required"`
Data struct {
Name string `json:"name" binding:"required"`
Slug string `json:"slug" binding:"required"`
}
}
As mentioned above, the workaround (bind twice) doesn't work with required fields.
+1 on this. Any updates or workarounds for required fields?
+1
+1
+1
+1
+1
+1
+1
ok here is an example :
// here ,we can use this struct in get method again.
type UserGetRequest struct {
Id models.Id `uri:"id" binding:"required"`
}
type UserUpdateRequest struct {
Nickname string `json:"nickname" `
}
func UserGet(context *gin.Context, domain *domains.Context) {
var (
locator = new(UserGetRequest)
)
if err = context.BindUri(locator); err != nil {
return
}
if user, err = upms.UserGet(domain, locator.Id); err == nil {
...
}
return
}
func UserUpdate(context *gin.Context) {
var (
locator = new(UserGetRequest)
request = new(UserUpdateRequest)
)
if err = context.BindUri(¶ms); err != nil {
return
}
if err = context.BindJSON(&request); err != nil {
return
}
var action = upms.UserUpdateAction{
Nickname: request.Nickname,
}
if user, err = upms.UserUpdate(domain, locator.Id, action); err == nil {
.....
}
return
}
Is it a good idea to support something like requried_in=json, required_in=uri? If it makes sense, I would like to create a pr.
This worked for me:
ok here is an example :
// here ,we can use this struct in get method again. type UserGetRequest struct { Id models.Id `uri:"id" binding:"required"` } type UserUpdateRequest struct { Nickname string `json:"nickname" ` } func UserUpdate(context *gin.Context) { var ( locator = new(UserGetRequest) request = new(UserUpdateRequest) ) if err = context.BindUri(¶ms); err != nil { return } if err = context.BindJSON(&request); err != nil { return } var action = upms.UserUpdateAction{ Nickname: request.Nickname, } if user, err = upms.UserUpdate(domain, locator.Id, action); err == nil { ..... } return }