-
Notifications
You must be signed in to change notification settings - Fork 8.6k
Description
Feature Description
Problem
There have been multiple issues raised and even a PR requesting a feature to allow Gin to bind headers, request path params, query params, and body in a single call:
- Bind JSON and URI #1824
- How to bind to a struct with json and header struct tags both ? #2309
- how to binding param and json #2535
- Binding URI and JSON on the same struct #2758
- Can i bind uri and query to a struct in one method? #2919
- How to support both URI and map parameter binding with shouldBind #4338
- Add a shortcut to bind uri and query at the same time #3095
Most of these show the standard workaround of a split-struct solution where 2 separate structs are used to bind uri and body separately in separate calls:
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
}
This is required to avoid violating the binding:required tags on all fields, since ShouldBindUri checks all binding tags even on non-uri fields. But this is also frustrating to many developers as highlighted by the large number of issue requests to add a method to bind all request parts at once.
Solution
To resolve this, we should have BindAll and ShouldBindAll methods that can bind these various request parts to a single struct based on the appropriate tags (eg uri vs form vs header), AND only apply binding validation after all fields and request parts have been processed and bound.
I will raise a PR with full unit tests like I did in my previous PR