Original author, public number [programmer reading], welcome to pay attention to the public number, reprint the article please indicate the source oh.

Wrote two in front of the article related to Gin framework to study, mainly about the installation of Gin framework, define the methods of dealing with the HTTP request and how to return data in different formats according to client demand, but missed a link among this, that is before returning to the data, how to get the client to bring in the HTTP request parameters, about this, We’ll talk about it in this article.

The Gin framework encapsulates the processing of HTTP request parameters and how to respond to them in the Gin.Conetxt structure, and provides a large number of methods for Gin.Context.

Here is the code for the gin.Context structure definition:

type Context struct {
    Request *http.Request
    Writer  ResponseWriter
    Params Params
    // Keys is a key/value pair exclusively for the context of each request.
    Keys map[string]interface{}
    // Errors is a list of errors attached to all the handlers/middlewares who used this context.
    Errors errorMsgs
    // Accepted defines a list of manually accepted formats for content negotiation.
    Accepted []string
    // contains filtered or unexported fields
}
Copy the code

From the above structural definition of gin.Context, gin.Context encapsulates http.Request and http.ResponseWriter

Get request parameters

1. Path

Path refers to the requested url of the domain name after starting/parts, such as the Denver nuggets homepage address: https://juejin.im/timeline, part/timeline is the path, you can use the gin, the Context of Param () method to get this part parameters.

func (c *Context) Param(key string) string
Copy the code

Use the Param() method to get the arguments in path:

r.GET("/user/:id",func(c *gin.Context){
    id := c.Param("id")})Copy the code

In addition to using the Param() method in gin.Context, you can also use the Params field in gin.Context to get the parameters in the path.

type Params []Param
func (ps Params) ByName(name string) (va string)
func (ps Params) Get(name string) (string, bool)
Copy the code

The following is an example of obtaining the parameters in path using the Params field in gin.Context:

r.GET("/user/:id",func(c *gin.Context){
    id,err := c.Params.Get("id")
    //id := c.Params.ByName("id")})Copy the code

2. Query

Query =%E6%96%87%E7%AB% A& type=all Query =%E6%96%87%E7%AB% A& type=all

https://juejin.im/search?query=%E6%96%87%E7%AB%A0&type=all
Copy the code

Gin.Context provides the following methods to get the parameters of the Query section.

1. Obtain a single parameter
func (c *Context) GetQuery(key string) (string, bool)
func (c *Context) Query(key string) string
func (c *Context) DefaultQuery(key, defaultValue string) string
Copy the code

GetQuery returns one more parameter of type error than Query. In fact, the Query method just wraps the GetQuery method and ignores the error returned by the GetQuery method. The DefaultQuery method returns a default value if no corresponding parameter value is retrieved.

The following is an example:

r.GET("/user", func(c *gin.Context) {
    id,_ := c.GetQuery("id")
    //id := c.Query("id")
    //id := c.DefaultQuery("id"."10")
    c.JSON(200,id)
})
Copy the code

Request: http://localhost:8080/user? id=11

Response: 11

2. Get the array

The difference between the GetQueryArray method and QueryArray is similar to that between GetQuery and Query.

func (c *Context) GetQueryArray(key string) ([]string, bool)
func (c *Context) QueryArray(key string) []string

Copy the code

The following is an example:

r.GET("/user", func(c *gin.Context) {
    ids := c.QueryArray("id")
    //id,_ := c.QueryArray("id")
    c.JSON(200,ids)
})
Copy the code

Request: http://localhost:8080/user? id=10&id=11&id=12

Response: [” 10 “, “11”, “12”]

3. Access to the map

The difference between the GetQueryArray method and QueryArray is similar to that between GetQuery and Query.

func (c *Context) QueryMap(key string) map[string]string
func (c *Context) GetQueryMap(key string) (map[string]string, bool)
Copy the code

The following is an example:

r.GET("/user", func(c *gin.Context) {
    ids := c.QueryMap("ids")
    //ids,_ := c.GetQueryMap("ids")
    c.JSON(200,ids)
})
Copy the code

Request: http://localhost:8080/user? ids[10]=zhang

Response: {” 10 “:” zhang “}

3. Body

Generally, HTTP Post request parameters are transmitted to the server through the body part, especially the data with a large amount of data or high security requirements, such as account password and other parameters in the login function.

Gin.Context provides the following four methods to retrieve data from the body, but it should be noted that the following four methods, Only body data can be retrieved if content-Type is Application/X-ww-form-urlencoded or multipart/form-data.

The following method is used in the same way as the above method to get a Query. The difference is only that the data source is different, so I won’t write the sample here.

func (c *Context) PostForm(key string) string
func (c *Context) PostFormArray(key string) []string
func (c *Context) PostFormMap(key string) map[string]string
func (c *Context) DefaultPostForm(key, defaultValue string) string
func (c *Context) GetPostForm(key string) (string, bool)
func (c *Context) GetPostFormArray(key string) ([]string, bool)
func (c *Context) GetPostFormMap(key string) (map[string]string, bool)
func (c *Context) GetRawData() ([]byte, error)
Copy the code

Data binding

In the previous example, we directly used the methods provided by gin.Context to retrieve the parameters brought in through the path, query, and body of the request. However, these methods did not deal with the more complex data structures in the request. For example, when the content-Type is Application /json or application/ XML, the data is very complex, so we need to use another method to get the data, which is called data binding.

The Gin framework encapsulates all data binding operations in the Gin/Binding package. Below are constants defined by the Gin/Binding package to illustrate the content-Type format supported by the Gin/Binding package.

const (
    MIMEJSON              = "application/json"
    MIMEHTML              = "text/html"
    MIMEXML               = "application/xml"
    MIMEXML2              = "text/xml"
    MIMEPlain             = "text/plain"
    MIMEPOSTForm          = "application/x-www-form-urlencoded"
    MIMEMultipartPOSTForm = "multipart/form-data"
    MIMEPROTOBUF          = "application/x-protobuf"
    MIMEMSGPACK           = "application/x-msgpack"
    MIMEMSGPACK2          = "application/msgpack"
    MIMEYAML              = "application/x-yaml"
)
Copy the code

The gin. Binding package also defines a processing structure for handling different content-type submitted data and makes it accessible to other packages in the form of variables, as follows:

var (
    JSON          = jsonBinding{}
    XML           = xmlBinding{}
    Form          = formBinding{}
    Query         = queryBinding{}
    FormPost      = formPostBinding{}
    FormMultipart = formMultipartBinding{}
    ProtoBuf      = protobufBinding{}
    MsgPack       = msgpackBinding{}
    YAML          = yamlBinding{}
    Uri           = uriBinding{}
)
Copy the code

In fact, we don’t need to call the gin/ Binding package code to complete the data binding function, because gin.Context already encapsulates many faster methods on top of gin.Context:

The related binding methods encapsulated in gin.Context are divided into Bind prefixed methods and ShouldBind prefixed methods. The difference between the two methods is that if the user input data does not conform to the corresponding format, A response with the HTTP status of 400 is directly returned to the client.

A set of methods prefixed with Bind

1. Path
func (c *Context) BindUri(obj interface{}) error
Copy the code

Code examples:

typeUser struct {Uid int // User id Username string // Username} funcmain() {
    r := gin.Default()
    r.GET("/bind/:uid/username", func(c *gin.Context) {
        var u User
        e := c.BindUri(&u)
        if e == nil{
            c.JSON(200,u)
        }
    })
    r.Run()
}

Copy the code

Request: zhang at http://localhost:8080/bind/1/

Input: {1,” zhang “}

2. Query
func (c *Context) BindQuery(obj interface{}) error
Copy the code

Code examples:

r.GET("/bind/:uid/username", func(c *gin.Context) {
    var u User
    e := c.BindQuery(&u)
    if e == nil{
        c.JSON(200,u)
    }
})
Copy the code

Request: http://localhost:8080/bind? Uid = 1 & username = xiao zhang

Output: {1,” zhang “}

3. Body

When we set different data formats for Body in AN HTTP request, we need to set the value of the corresponding header content-Type, which is commonly used when the following three methods are provided for json, XML, YAMl, and gin.Context to bind the data in the Body.

func (c *Context) BindJSON(obj interface{}) error
func (c *Context) BindXML(obj interface{}) error
func (c *Context) BindYAML(obj interface{}) error
Copy the code

In addition to the above three methods, the more commonly used Bind() method, Bind(), automatically selects a different binding Type based on the value of the Content-Type.

func (c *Context) Bind(obj interface{}) error
Copy the code

The sample

r.POST("bind",func(c *gin.Context){
    u := User{}
    c.Bind(&u)
})
Copy the code

The above methods all get a fixed content-Type or automatically select the binding type based on the content-Type. We can also use the following two methods to select the binding type ourselves.

The value of the second argument to the next two methods is a constant defined in gin. Binding, as we discussed above.

func (c *Context) BindWith(obj interface{}, b binding.Binding) error
func (c *Context) MustBindWith(obj interface{}, b binding.Binding) error
Copy the code

The sample

r.POST("bind",func(c *gin.Context){
	u := User{}
	c.BindWith(&u,binding.JSON)
    c.MustBindWith(&u,binding.JSON)
})
Copy the code

A series of methods prefixed with ShouldBind

The corresponding method prefixed with ShouldBind is used in much the same way as the Bind method, so there is no code to demonstrate it below.

1. Path
func (c *Context) ShouldBindUri(obj interface{}) error
Copy the code
2. Query
func (c *Context) ShouldBindQuery(obj interface{}) error
Copy the code
3. Body
func (c *Context) ShouldBind(obj interface{}) error func (c *Context) ShouldBindJSON(obj interface{}) error func (c *Context) ShouldBindXML(obj interface{}) error func (c *Context) ShouldBindYAML(obj interface{}) error func (c *Context)  ShouldBindBodyWith(obj interface{}, bb binding.BindingBody) (err error) func (c *Context) ShouldBindWith(obj interface{}, b binding.Binding) errorCopy the code

summary

Gin in the.net framework/HTTP package encapsulates many method, on the basis of that we can receive the client transfer data from a variety of different formats, but after getting data from the client, or to verify the data whether legal or whether we want to be, this is Gin the framework of knowledge about data validators, have a chance to write this article.


Your attention is the biggest encouragement on my writing road!