You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This proposal suggests adding a new All() binding method to the Fiber framework that would bind data from multiple request sources (query parameters, body, URL parameters, headers, cookies) into a single struct using a single method call.
Motivation
Currently, developers need to call multiple binding methods (c.BodyParser(), c.QueryParser(), etc.) to gather data from different sources. This leads to repetitive code and requires developers to manually handle conflicts when the same field might be present in multiple sources.
Proposed API
// All binds data from multiple sources into a single structfunc (b*Bind) All(outany) error
Usage Examples
Basic Usage
typeUserstruct {
// Field can be bound from any sourceIDint`param:"id" query:"id" json:"id" form:"id"`// Fields with source-specific tagsNamestring`query:"name" json:"name" form:"name"`Emailstring`json:"email" form:"email"`Rolestring`header:"x-user-role"`SessionIDstring`cookie:"session_id"`// File upload supportAvatar*multipart.FileHeader`form:"avatar"`
}
app.Post("/users/:id", func(c fiber.Ctx) error {
user:=new(User)
iferr:=c.Bind().All(user); err!=nil {
returnerr
}
// All available data is now bound to the user structreturnc.JSON(user)
})
When the same field is present in multiple sources, we need a clear precedence rule. Proposed default precedence order (highest to lowest):
URL Parameters (:param)
Body (JSON/XML/Form)
Query parameters
Headers
Cookies
This order follows a general principle of specificity (URL param is most specific to this request), followed by explicit data (body), then ambient request data (query, headers, cookies).
Custom Source Precedence
For flexibility, developers can define custom precedence with an optional binding_source tag:
typeProductstruct {
// Override default precedence (query takes precedence over body)IDint`param:"id" query:"id" json:"id" binding_source:"param,query,body"`// Only bind from form data, ignore other sourcesImage*multipart.FileHeader`form:"image" binding_source:"form"`
}
Empty Values Handling
By default, empty values from higher-precedence sources won't overwrite non-empty values from lower-precedence sources.
Example: If a field has value "foo" in the body but an empty string in the query, the final value would be "foo".
This behavior can be changed with a configuration option:
Parse each data source independently (reusing existing binding logic)
Apply values to the output struct according to precedence rules
Handle special cases like file uploads appropriately
Provide detailed error messages for binding failures
// Pseudo-implementationfunc (b*Bind) All(outany) error {
// Store binding errors to report after all attemptsvarbindingErrors []error// Get values from each sourceparamValues, paramErr:=b.getParamValues()
ifparamErr!=nil {
bindingErrors=append(bindingErrors, paramErr)
}
bodyValues, bodyErr:=b.getBodyValues()
ifbodyErr!=nil {
bindingErrors=append(bindingErrors, bodyErr)
}
queryValues, queryErr:=b.getQueryValues()
ifqueryErr!=nil {
bindingErrors=append(bindingErrors, queryErr)
}
// ... similar for headers and cookies// Apply values according to precedenceiferr:=b.applyValues(out, paramValues, bodyValues, queryValues, headerValues, cookieValues); err!=nil {
returnerr
}
// If we had any binding errors but still managed to bind some values, report themiflen(bindingErrors) >0 {
returnfmt.Errorf("partial binding completed with errors: %v", bindingErrors)
}
returnnil
}
Performance Considerations
Avoid unnecessary parsing (lazy-load each source)
Reuse existing binding mechanisms where possible
Minimize allocations for property mapping
Consider caching struct field metadata for repeated bindings
Benefits
Simplified API for handling data from multiple sources
Reduced code duplication in handlers
Clearer intent in struct definitions
Consistent handling of conflicts between sources
Better integration with validation libraries
Aligns with RESTful practices where resources can be identified and manipulated through multiple means
Future Extensions
Support for binding to nested structs from different sources
Custom binding functions for specific fields
Built-in type conversion for common cases (string to int, etc.)
Integration with schema validation
This proposal aligns with Fiber's design principles of Express.js compatibility while offering Go-idiomatic features that improve developer experience.
Universal Request Binding: ctx.Bind().All()
Overview
This proposal suggests adding a new
All()
binding method to the Fiber framework that would bind data from multiple request sources (query parameters, body, URL parameters, headers, cookies) into a single struct using a single method call.Motivation
Currently, developers need to call multiple binding methods (c.BodyParser(), c.QueryParser(), etc.) to gather data from different sources. This leads to repetitive code and requires developers to manually handle conflicts when the same field might be present in multiple sources.
Proposed API
Usage Examples
Basic Usage
With Validation
Source Precedence
When the same field is present in multiple sources, we need a clear precedence rule. Proposed default precedence order (highest to lowest):
:param
)This order follows a general principle of specificity (URL param is most specific to this request), followed by explicit data (body), then ambient request data (query, headers, cookies).
Custom Source Precedence
For flexibility, developers can define custom precedence with an optional
binding_source
tag:Empty Values Handling
By default, empty values from higher-precedence sources won't overwrite non-empty values from lower-precedence sources.
Example: If a field has value "foo" in the body but an empty string in the query, the final value would be "foo".
This behavior can be changed with a configuration option:
Implementation Details
Integration with Existing Bind Interface
The proposed feature would extend the existing
Bind
interface:Internal Implementation Approach
Performance Considerations
Benefits
Future Extensions
This proposal aligns with Fiber's design principles of Express.js compatibility while offering Go-idiomatic features that improve developer experience.
References
*multipart.FileHeader
fields to Multipart Binder #2002 (the multipart file binding issue)Requested by: @ReneWerner87
The text was updated successfully, but these errors were encountered: