Request input relies on the ghttp.Request
object, which inherits from the underlying http.Request
object. The ghttp.Request
contains a corresponding response output object Response
for the current request, used for data return processing.
Related methods: https://pkg.go.dev/github.com/gogf/gf/v2/net/ghttp#Request
Brief Introduction
As you can see, the parameter retrieval methods of the Request
object are quite abundant, with common methods as follows:
Common Methods | Description |
---|---|
Get | A common method for simplified parameter retrieval, alias for GetRequest . |
GetQuery | Retrieves parameters passed via GET method, including Query String and Body parameter parsing. |
GetForm | Retrieves parameters passed via form method. The Content-Type for form submissions is often application/x-www-form-urlencoded , application/form-data , multipart/form-data , multipart/mixed , etc. |
GetRequest | Retrieves all parameters submitted by the client, covering parameters based on priority without distinguishing submission methods. |
GetStruct | Binds all request parameters of a specified submission type to a specified struct object. Note that the given parameter is a pointer to an object. In most scenarios, the Parse method is often used to convert request data into a request object, as detailed in subsequent chapters. |
GetBody/GetBodyString | Retrieves the raw data submitted by the client; this data is the raw data written into the body by the client, regardless of HTTP Method , for instance, when the client submits JSON/XML data format, this method can be used to get the original submitted data. |
GetJson | Automatically parses the original request information into a gjson.Json object pointer and returns it. The gjson.Json object is specifically introduced in the chapter General Codec. |
Exit | Used for request flow control exit, as detailed in the subsequent explanations in this chapter. |
Submission Method
In the GoFrame
framework, parameter retrieval is not distinguished by HTTP Method
but by parameter submission type. For example, when form parameters are submitted via HTTP Method: POST, INPUT, DELETE
, the parameters are retrieved on the server side not through GetPost
/GetInput
/GetDelete
, but uniformly through GetForm
method for form parameters, which applies similarly to other HTTP Methods
.
Under the GoFrame
framework, there are several submission types:
Submission Type | Description |
---|---|
Router | Route Parameters. Derived from route rule matching. |
Query | Query Parameters. Parsing Query String parameters in URL , such as id=1&name=john in http://127.0.0.1/index?id=1&name=john . |
Form | Form Parameters. The most common submission method, with the submitted Content-Type often being: application/x-www-form-urlencoded , multipart/form-data , multipart/mixed . |
Body | Content Parameters. Parameters obtained and parsed from Body , JSON /XML requests often use this method for submission. |
Custom | Custom Parameters, usually managed in server-side middleware or service functions via SetParam/GetParam methods. |
Parameter Type
The parameter retrieval methods can automatically convert types of data with specified keys, for example: http://127.0.0.1:8199/?amount=19.66
, retrieving with Get(xxx).String()
will return the string type 19.66
, while Get(xxx).Float32()
/Get(xxx).Float64()
will respectively return the float32
and float64
numeric type 19.66
. However, Get(xxx).Int()
/Get(xxx).Uint()
will return 19
(if the parameter is a string of float type, it will be converted to integer by rounding down).
tip
Smart of you to notice that all retrieved parameters are generic variables, and based on these generic variables, you can call corresponding methods to convert them into respective data types according to your needs.
Usage example:
package main
import (
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/net/ghttp"
)
func main() {
s := g.Server()
s.BindHandler("/", func(r *ghttp.Request) {
r.Response.Writeln(r.Get("amount").String())
r.Response.Writeln(r.Get("amount").Int())
r.Response.Writeln(r.Get("amount").Float32())
})
s.SetPort(8199)
s.Run()
}
After execution, visiting the address http://127.0.0.1:8199/?amount=19.66 outputs:
19.66
19
19.66
Parameter Priority
Let’s consider a scenario, what happens when parameters with the same name exist in different submission methods? In the GoFrame
framework, according to different retrieval methods, it acquires them based on different priorities, the parameter submitted by the method with higher priority will override the same-named parameters from other methods. The priority rules are as follows:
Get
andGetRequest
methods:Router < Query < Body < Form < Custom
, meaning custom parameters have the highest priority, followed byForm
parameters, thenBody
parameters, and so on. For example, if bothQuery
andForm
submit parameters with the same name,id
, with values1
and2
respectively,Get("id")
/GetForm("id")
will return2
, whileGetQuery("id")
will return1
.GetQuery
method:Query > Body
, meaningquery string
parameters override same-named parameters inBody
. For instance,Query
andBody
both submit a parameter namedid
with values1
and2
, respectively,Get("id")
will return2
, andGetQuery("id")
will return1
.GetForm
method: Since this method is only for retrievingForm
parameters, there isn’t much priority difference.
Usage example:
package main
import (
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/net/ghttp"
)
func main() {
s := g.Server()
s.BindHandler("/input", func(r *ghttp.Request) {
r.Response.Writeln(r.Get("amount"))
})
s.BindHandler("/query", func(r *ghttp.Request) {
r.Response.Writeln(r.GetQuery("amount"))
})
s.SetPort(8199)
s.Run()
}
After execution, we test using the curl
tool:
$ curl -d "amount=1" -X POST "http://127.0.0.1:8199/input?amount=100"
1
$ curl -d "amount=1" -X POST "http://127.0.0.1:8199/query?amount=100"
100
As observed, when accessing the /input
route, the method used the Get
method to retrieve the amount
parameter, according to the same-name priority rule, returning 1
, the parameter passed in the body
. When accessing through the /query
route, the method internally used the GetQuery
method to get the amount
parameter, thus it retrieved the query string
parameter’s amount
value, returning 100
.
Case Sensitivity
It is important to note that parameter names are case-sensitive, for instance, parameters name
and Name
submitted by the client are two different parameters. Since the server-side retrieves parameters by string name by default, case sensitivity doesn’t pose much issue, but it might need some attention if the server-side is receiving an API object. Let’s look at an example.
Server-side:
package main
import (
"context"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/net/ghttp"
)
type Controller struct{}
type PathReq struct {
g.Meta `path:"/api/v1/*path" method:"post"`
Path string
}
type PathRes struct {
Path string
}
func (c *Controller) Path(ctx context.Context, req *PathReq) (res *PathRes, err error) {
return &PathRes{Path: req.Path}, nil
}
func main() {
s := g.Server()
s.SetPort(8199)
s.Use(ghttp.MiddlewareHandlerResponse)
s.Group("/", func(group *ghttp.RouterGroup) {
group.Bind(&Controller{})
})
s.Run()
}
The original intention of the server-side API design is to define a route parameter path
and receive it through the Path
attribute of the API
object.
Client-side:
package main
import (
"fmt"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gctx"
)
func main() {
var (
ctx = gctx.New()
client = g.Client()
)
client.SetPrefix("http://127.0.0.1:8199")
for i := 0; i < 10; i++ {
fmt.Println(client.PostContent(ctx, "/api/v1/user/info", `{"Path":"user/profile"}`))
}
}
Based on our understanding, after submission by the client, the server should receive the route parameter path
as user/info
. However, due to a program BUG
, strangely, the client also submitted a JSON
in the Body
, with parameter name Path
and parameter value user/profile
. Now, which value will the server’s API
object attribute Path
hold?
Running the client repeatedly, the output results are all:
{"code":0,"message":"","data":{"Path":"user/profile"}}
{"code":0,"message":"","data":{"Path":"user/profile"}}
{"code":0,"message":"","data":{"Path":"user/profile"}}
{"code":0,"message":"","data":{"Path":"user/profile"}}
{"code":0,"message":"","data":{"Path":"user/profile"}}
{"code":0,"message":"","data":{"Path":"user/profile"}}
{"code":0,"message":"","data":{"Path":"user/profile"}}
{"code":0,"message":"","data":{"Path":"user/profile"}}
{"code":0,"message":"","data":{"Path":"user/profile"}}
{"code":0,"message":"","data":{"Path":"user/profile"}}
This means the parameters are all values submitted in Body
, not the values from the route parameters. In fact, due to the case-sensitive nature of parameters, the server received two parameters at this time, one is the route parameter path
, the other is the Path
submitted in Body JSON
. When converting to an API
parameter object, the server uses the value from Body JSON
since the attribute Path
matches the Path
in Body JSON
more closely.