Is it possible to bind `uri` and `json` for the same struct?
Eg. for updateAccount API, How to bind uri and json for the same struct?
type updateAccountRequest struct {
ID int64 `uri:"id" binding:"required,min=1"`
Currency string `json:"currency" binding:"required,currency"`
}
func (server *Server) updateArticle(ctx *gin.Context) {
var req updateAccountRequest
if err := ctx.ShouldBindUri(&req); err != nil {
// send 400 Bad Request to the client
ctx.JSON(http.StatusBadRequest, errorResponse(err))
return
}
if err := ctx.ShouldBindJSON(&req); err != nil {
// send 400 Bad Request to the client
ctx.JSON(http.StatusBadRequest, errorResponse(err))
return
}
}
the code above does not work.
Does anyone know? Thanks in advance
I use result here: https://github.com/gin-gonic/gin/issues/1824#issuecomment-475968345 but I wonder whether there is a better solution
I use result here: gin-gonic/gin#1824 (comment) but I wonder whether there is a better solution
type updateAccountRequest struct {
ID int64 `uri:"id" binding:"required,min=1"`
Balance int64 `json:"balance"`
}
func (server *Server) updateAccountHandler(ctx *gin.Context) {
var req updateAccountRequest
if err := ctx.ShouldBindUri(&req); err != nil {
ctx.JSON(http.StatusBadRequest, errorResponse(err))
return
}
if err := ctx.ShouldBindJSON(&req); err != nil {
ctx.JSON(http.StatusBadRequest, errorResponse(err))
return
}
arg := db.UpdateAccountParams{
ID: req.ID,
Balance: req.Balance,
}
updatedAccount, err := server.store.UpdateAccount(ctx, arg)
if err != nil {
if err == sql.ErrNoRows {
ctx.JSON(http.StatusNotFound, errorResponse(err))
return
}
ctx.JSON(http.StatusInternalServerError, errorResponse(err))
return
}
ctx.JSON(http.StatusOK, updatedAccount)
}
@TaylorDurden thanks for help. However, if I recall correctly, this may not work.
@TaylorDurden thanks for help. However, if I recall correctly, this may not work.
@TaylorDurden thanks for help. However, if I recall correctly, this may not work.
https://github.com/TaylorDurden/go-simple-bank/pull/4
You can try it in my PR branch. Maybe the new version gin resolved this.
@chengr4
I guess that maybe you were testing a 400 Bad Request to the API client without currency field.
If you mark the currency field not required, this field won't be validated for 1 struct.
// this required binding will fail ctx.ShouldBindUri validation
Currency string `json:"currency" binding:"required,currency"`
// this code will validate the struct fileds, if you did not pass the Currency field
ctx.ShouldBindUri(&req)
FYI: https://github.com/gin-gonic/gin/blob/cc4e11438cd6c0bcc632fe3492d3817dfa21c337/context.go#L763 https://github.com/gin-gonic/gin/blob/cc4e11438cd6c0bcc632fe3492d3817dfa21c337/binding/uri.go#L17
@TaylorDurden But I usually want to validate it
@TaylorDurden But I usually want to validate it
Then you should use another struct for this param...since it is from request body and use ShouldBindJSON to parse & validate it. Although it is not a clean solution but it works as you metioned above...