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:

  1. Properties in the struct that need to be bound must be public properties (first letter capitalized).
  2. Parameter names will automatically match with struct properties in a case-insensitive manner and ignoring -/_/space symbols.
  3. 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:

  1. map key name struct property Match?
  2. name Name match
  3. Email Email match
  4. nickname NickName match
  5. NICKNAME NickName match
  6. Nick-Name NickName match
  7. nick_name NickName match
  8. nick name NickName match
  9. NickName Nick_Name match
  10. Nick-name Nick_Name match
  11. nick_name Nick_Name match
  12. 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:

  1. type User struct{
  2. Id int
  3. Name string
  4. Pass1 string `p:"password1"`
  5. Pass2 string `p:"password2"`
  6. }

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.

Request - Parameter Binding - 图1warning

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:

  1. package main
  2. import (
  3. "github.com/gogf/gf/v2/frame/g"
  4. "github.com/gogf/gf/v2/net/ghttp"
  5. )
  6. type RegisterReq struct {
  7. Name string
  8. Pass string `p:"password1"`
  9. Pass2 string `p:"password2"`
  10. }
  11. type RegisterRes struct {
  12. Code int `json:"code"`
  13. Error string `json:"error"`
  14. Data interface{} `json:"data"`
  15. }
  16. func main() {
  17. s := g.Server()
  18. s.BindHandler("/register", func(r *ghttp.Request) {
  19. var req *RegisterReq
  20. if err := r.Parse(&req); err != nil {
  21. r.Response.WriteJsonExit(RegisterRes{
  22. Code: 1,
  23. Error: err.Error(),
  24. })
  25. }
  26. // ...
  27. r.Response.WriteJsonExit(RegisterRes{
  28. Data: req,
  29. })
  30. })
  31. s.SetPort(8199)
  32. s.Run()
  33. }

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:

  1. $ curl "http://127.0.0.1:8199/register?name=john&password1=123&password2=456"
  2. {"code":0,"error":"","data":{"Name":"john","Pass":"123","Pass2":"456"}}
  3. $ curl -d "name=john&password1=123&password2=456" -X POST "http://127.0.0.1:8199/register"
  4. {"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.