Parameter Binding
Parameter binding is a common requirement in request processing. We recommend binding request parameters to struct
objects for structured parameter handling. The GoFrame
framework provides convenient parameter binding capabilities, supporting binding of client-submitted parameters such as Query
parameters, form parameters, content parameters, JSON/XML
, etc., to specified struct
objects, and supports maintaining the mapping relationship between submitted parameters and struct
properties.
Parameter binding methods use the Parse
method or Get*Struct
methods of the Request
object. For specific method definitions, please refer to the API documentation: https://pkg.go.dev/github.com/gogf/gf/v2/net/ghttp#Request
Parameter Mapping
Default Rules
When binding client-submitted parameters to server-defined struct
properties, you can use the default mapping rules, which is very convenient. The default binding rules are as follows:
- Properties in the
struct
that need to be bound must bepublic properties
(first letter capitalized). - Parameter names will automatically match with
struct
properties in acase-insensitive
manner and ignoring-/_/space
symbols. - If the match is successful, the parameter value will be bound to the property; if it cannot be matched, the parameter will be ignored.
Here are some matching examples:
map key name struct property Match?
name Name match
Email Email match
nickname NickName match
NICKNAME NickName match
Nick-Name NickName match
nick_name NickName match
nick name NickName match
NickName Nick_Name match
Nick-name Nick_Name match
nick_name Nick_Name match
nick name Nick_Name match
Since the underlying parameter binding implementation uses the gconv
module, it also supports c/gconv/json
tags. For more detailed rules, please refer to the Type Conversion - Struct chapter.
Custom Rules
Please use custom binding rules in business scenarios where struct properties and parameter names differ significantly; otherwise, use the default parameter binding rules. This is because a large number of custom rule tags will increase code maintenance costs.
Custom parameter binding rules can be implemented by binding tags
to struct
properties. The tag
names can be p/param/params
. For example:
type User struct{
Id int
Name string
Pass1 string `p:"password1"`
Pass2 string `p:"password2"`
}
Here we use the p
tag to specify which parameter should bind to which property. The password1
parameter will bind to the Pass1
property, and password2
will bind to the Pass2
property. Other properties can use the default binding rules without setting tags
.
Parse
Binding
We can use the Parse
method to implement parameter binding to structs. This method is a convenient method that will automatically perform binding and data validation internally, but if there are no validation tags
bound in the struct
, validation logic will not be executed.
Starting from GoFrame v2
, we recommend using a structured approach to define routing methods for easier management of request/response structures and their parameter binding. Please refer to: Standard Router
Usage example:
package main
import (
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/net/ghttp"
)
type RegisterReq struct {
Name string
Pass string `p:"password1"`
Pass2 string `p:"password2"`
}
type RegisterRes struct {
Code int `json:"code"`
Error string `json:"error"`
Data interface{} `json:"data"`
}
func main() {
s := g.Server()
s.BindHandler("/register", func(r *ghttp.Request) {
var req *RegisterReq
if err := r.Parse(&req); err != nil {
r.Response.WriteJsonExit(RegisterRes{
Code: 1,
Error: err.Error(),
})
}
// ...
r.Response.WriteJsonExit(RegisterRes{
Data: req,
})
})
s.SetPort(8199)
s.Run()
}
In this example, we defined two structs: RegisterReq
for binding request parameters and RegisterRes
for response data.
We use r.Parse(&req)
to bind client-submitted parameters to a RegisterReq
object. When the binding is successful, the req
variable will be initialized with the bound values (by default it's nil
), otherwise, this method returns err
and the req
variable remains nil
. The response data structure is defined through RegisterRes
, and the return format is JSON
, implemented through r.Response.WriteJsonExit
. This method converts RegisterRes
to JSON
format according to its internal defined json
tags and exits the current service method.
To demonstrate the binding effect, here we return the RegisterReq
object in the normal return result's Data
property. Since this object doesn't have json
tags bound, the returned JSON
fields will be its property names.
Let's test it with the curl
tool:
$ curl "http://127.0.0.1:8199/register?name=john&password1=123&password2=456"
{"code":0,"error":"","data":{"Name":"john","Pass":"123","Pass2":"456"}}
$ curl -d "name=john&password1=123&password2=456" -X POST "http://127.0.0.1:8199/register"
{"code":0,"error":"","data":{"Name":"john","Pass":"123","Pass2":"456"}}
We used both GET
and POST
submission methods for testing, and we can see that the server can perfectly bind the submitted parameters to the struct object.