• Introduction to the
  • Read request parameters
    • Parameters in path
    • Parameters in query
    • Arguments in from
    • Model binding
  • Returns a response
  • conclusion
  • Code for the current section

Introduction to the

The most basic thing to do with a Web framework is to read and write requests, and Gin supports a wide variety of request parameters as well as a wide variety of responses.

Read request parameters

Parameters in path

Use Param() to get the arguments in path.

Parameters defined in path have two formats :name starts with a colon, and *action starts with an asterisk.

:name must match, must have a value, cannot be empty. In the following code, the first example does this by using :name to represent the user’s name, so that any user name can be represented in the path.

* Action is optional. If it does not exist, it will be ignored, such as /user/ John /, and /user/ John/will be jumped to /user/ John /.

// This handler will match /user/john but will not match /user/ or /user
router.GET("/user/:name".func(c *gin.Context) {
  name := c.Param("name")
  c.String(http.StatusOK, "Hello %s", name)
})

// However, this one will match /user/john/ and also /user/john/send
// If no other routers match /user/john, it will redirect to /user/john/
router.GET("/user/:name/*action".func(c *gin.Context) {
  name := c.Param("name")
  action := c.Param("action")
  message := name + " is " + action
  c.String(http.StatusOK, message)
})
Copy the code

Parameters in query

The parameters in Query can be obtained using Query() and DefaultQuery(), with the latter using the second parameter as the default value.

// Query string parameters are parsed using the existing underlying request object.
// The request responds to a url matching:  /welcome?firstname=Jane&lastname=Doe
router.GET("/welcome".func(c *gin.Context) {
  firstname := c.DefaultQuery("firstname"."Guest")
  lastname := c.Query("lastname") // shortcut for c.Request.URL.Query().Get("lastname")

  c.String(http.StatusOK, "Hello %s %s", firstname, lastname)
})
Copy the code

Arguments in from

For parameters in a form, there are methods similar to Query, PostForm and DefaultPostForm.

router.POST("/form_post".func(c *gin.Context) {
  message := c.PostForm("message")
  nick := c.DefaultPostForm("nick"."anonymous")

  c.JSON(200, gin.H{
    "status":  "posted"."message": message,
    "nick":    nick,
  })
})
Copy the code

Model binding

The above methods of obtaining parameters are fairly general, but I think the most useful is the model binding.

The model binding first defines a struct, the struct needs to set the corresponding tag, that is, the fields inside the backquotes, and then fills the struct with the corresponding data, that is, the binding.

/ / bind JSON
type Login struct {
	User     string `form:"user" json:"user" xml:"user" binding:"required"`
	Password string `form:"password" json:"password" xml:"password" binding:"required"`
}

JSON ({"user": "manu", "password": "123"})
router.POST("/loginJSON".func(c *gin.Context) {
  var json Login
  iferr := c.ShouldBindJSON(&json); err ! =nil {
    c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
    return
  }

  ifjson.User ! ="manu"|| json.Password ! ="123" {
    c.JSON(http.StatusUnauthorized, gin.H{"status": "unauthorized"})
    return
  }

  c.JSON(http.StatusOK, gin.H{"status": "you are logged in"})})// bind XML (
/ / 
      
//	<root>
// 
      
       user
      
// 
      
       123
      
//	</root>)
router.POST("/loginXML".func(c *gin.Context) {
  var xml Login
  iferr := c.ShouldBindXML(&xml); err ! =nil {
    c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
    return
  }

  ifxml.User ! ="manu"|| xml.Password ! ="123" {
    c.JSON(http.StatusUnauthorized, gin.H{"status": "unauthorized"})
    return
  }

  c.JSON(http.StatusOK, gin.H{"status": "you are logged in"})})// Bind the HTML form (user=manu&password=123)
router.POST("/loginForm".func(c *gin.Context) {
  var form Login
  // Infer which binder to use based on the Content-Type Header.
  iferr := c.ShouldBind(&form); err ! =nil {
    c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
    return
  }

  ifform.User ! ="manu"|| form.Password ! ="123" {
    c.JSON(http.StatusUnauthorized, gin.H{"status": "unauthorized"})
    return
  }

  c.JSON(http.StatusOK, gin.H{"status": "you are logged in"})})Copy the code

The code above shows three different bindings, a jSON-formatted request body for binding, an XML request body, and a normal form.

Query is also marked with a form tag.

You can also bind headers (using Header tags) and URIs (using Uri tags), and so on.

Returns a response

There are also multiple types of data response formats for requests, supporting XML, JSON, YAML, and ProtoBuf.

func main(a) {
	r := gin.Default()

	// gin.H is a shortcut for map[string]interface{}
	r.GET("/someJSON".func(c *gin.Context) {
		c.JSON(http.StatusOK, gin.H{"message": "hey"."status": http.StatusOK})
	})

	r.GET("/moreJSON".func(c *gin.Context) {
		// You also can use a struct
		var msg struct {
			Name    string `json:"user"`
			Message string
			Number  int
		}
		msg.Name = "Lena"
		msg.Message = "hey"
		msg.Number = 123
		// Note that msg.Name becomes "user" in the JSON
		// Will output : {"user": "Lena", "Message": "hey", "Number": 123}
		c.JSON(http.StatusOK, msg)
	})

	r.GET("/someXML".func(c *gin.Context) {
		c.XML(http.StatusOK, gin.H{"message": "hey"."status": http.StatusOK})
	})

	r.GET("/someYAML".func(c *gin.Context) {
		c.YAML(http.StatusOK, gin.H{"message": "hey"."status": http.StatusOK})
	})

	r.GET("/someProtoBuf".func(c *gin.Context) {
		reps := []int64{int64(1), int64(2)}
		label := "test"
		// The specific definition of protobuf is written in the testdata/protoexample file.
		data := &protoexample.Test{
			Label: &label,
			Reps:  reps,
		}
		// Note that data becomes binary data in the response
		// Will output protoexample.Test protobuf serialized data
		c.ProtoBuf(http.StatusOK, data)
	})

	// Listen and serve on 0.0.0.0:8080
	r.Run(": 8080")}Copy the code

This is more than enough for API services, mainly JSON output. If you need high performance, you can use ProtoBuf, but this is not human-readable, so JSON is generally sufficient.

conclusion

I mainly showed you how to use Gin to read a request and return a response. This section is the foundation of the Web framework, and the usefulness of the framework depends largely on this section.

Code for the current section

As version V0.6.0