Gin Framework – Part 3

Introduction

The routing function of the Gin framework is designed based on httprouter. httprouter is a Golang implemented routing component; it uses the data structure of the radix tree (also known as radix trie or compressed prefix tree) to maintain the mapping routing relationship and route quickly through the prefix tree. Simultaneously, the interface implemented by the structure in it can be used as a HttpRouter release.

A radix tree (Radix Tree), also known as PAT a bit tree (Patricia-trie or crit-bit tree), is a more space-efficient prefix tree (Trie Tree). For each radix tree node, if the node is the only subtree, it is merged with the parent node.

Hori Systems – Radix Tree

HTTP Method

Common related methods ( ) have been encapsulated in the Gin framework, and direct calls will quickly register associated routes. The file location of the source code: HTTP GET, POST, PUT, DELETE, HEAD, …e.t.c.

// main.go code
package main
import (
	"github.com/gin-gonic/gin" // Introduce Gin framework
	"go_use/practise" // Introduced using the sample code package
)
func main() {
	// Create a default routing engine
	engine := gin.Default()
	// Invoke the HTTP method route
	practise.UseHttp(engine)
	_ = engine.Run(":9090")
}

// go_use/practise/routing_use.go code
// Learn to use HTTP methods
func UseHttp(engine *gin.Engine)  {
	// Use the Get method
	engine.GET("/get", func(context *gin.Context) {
		context.JSON(200,gin.H{"msg":"request succeeded","method":"get"})
	})
	// Use Post method
	engine.POST("/post", func(context *gin.Context) {
		context.JSON(200,gin.H{"msg":"request succeeded","method":"post"})
	})
	// Using the PUT method
	engine.PUT("/put", func(context *gin.Context) {
		context.JSON(200,gin.H{"msg":"request succeeded","method":"put"})
	})
	// Use the DELETE method
	engine.DELETE("/del", func(context *gin.Context) {
		context.JSON(200,gin.H{"msg":"request succeeded","method":"del"})
	})
	// Use the HEAD method
	engine.HEAD("/head", func(context *gin.Context) {
		context.JSON(200,gin.H{"msg":"request succeeded","method":"head"})
	})
}

Startup log output:

[GIN-debug] [WARNING] Creating an Engine instance with the Logger and Recovery middleware already attached.

[GIN-debug] [WARNING] Running in "debug" mode. Switch to "release" mode in production.
 - using env:   export GIN_MODE=release
 - using code:  gin.SetMode(gin.ReleaseMode)

[GIN-debug] GET    /get                      --> go_use/practise.UseHttp.func1 (3 handlers)
[GIN-debug] POST   /post                     --> go_use/practise.UseHttp.func2 (3 handlers)
[GIN-debug] PUT    /put                      --> go_use/practise.UseHttp.func3 (3 handlers)
[GIN-debug] DELETE /del                      --> go_use/practise.UseHttp.func4 (3 handlers)
[GIN-debug] HEAD   /head                     --> go_use/practise.UseHttp.func5 (3 handlers)
[GIN-debug] Environment variable PORT is undefined. Using port :9090 by default
[GIN-debug] Listening and serving HTTP on :9090

Example of calling:

# GET request 
$ curl -X GET http://127.0.0.1:9090/get
{"method": "get", "msg": "Request successful" }%
 #The route that receives the post using the GET request will report an 
error$ curl -X GET http://127.0.0.1:9090/post
404 page not found%
# POST request 
$ curl -X POST http://127.0.0.1:9090/post
{"method": "post", "msg" : "Request successful" }%
 # PUT request 
$ curl -X PUT http://127.0.0.1:9090/put
{"method" : "put", "msg" : "Request successful" }%
# DELETE request 
$ curl -X DELETE http://127.0.0.1:9090/del
{"method" : "del", "msg" : "Request successful" }%
# HEAD request 
$ curl -i -X ​​HEAD http://127.0.0.1:9090/head
Warning: Setting custom HTTP method to HEAD with -X/--request may not work the
Warning: way you want. Consider using -I/--head instead.
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Date: Mon, 17 May 2021 08:55:19 GMT
Content-Length: 38

It should be noted that when a route is registered as a specified HTTP method, it must be requested in the same way, otherwise it will return: 404 page not found

Match all HTTP requests

Using Any methods, you can match all HTTP methods (GET, POST, PUT, PATCH, HEAD, OPTIONS, DELETE, CONNECT, TRACE)

The usage example is as follows:

func  main () {
	 // Create a default routing engine 
	engine := gin.Default()
	 // Match HTTP method method 
	engine.Any ("/all", func(context  * gin. Context) {
		 context.JSON(200 ,gin.H{"msg" : "success" })
	})
	_ = engine.Run(":9090")
}

Registration Rules

Definitions

According to the above example, HTTP the rules for registering method routing can be summarized as follows:

// engine := gin.Default()
engine.MethodName(path string, ...HandlerFunc)
  • path: represents the path.
  • ...HandlerFunc: One or more handler functions that receive requests.

Upload multiple HandlerFunc examples

package main

import (
	"github.com/gin-gonic/gin"  // Import Gin framework
)

func  main () {
	 // Create a default routing engine 
	engine := gin.Default()
	 // Register a route and receive two HandlerFunc 
	engine.GET ("/handler", handFuncA, handFuncB)
	_ = engine.Run(":9090")
}

func handFuncA(ctx *gin.Context) {
	ctx.JSON(200, gin.H{"msg": "handFuncA"})
}

func handFuncB(ctx *gin.Context) {
	ctx.JSON(200, gin.H{"msg": "handFuncB"})
}

Request output:

$ curl -X GET http://127.0.0.1:9090/handler
{"msg":"handFuncA"}{"msg":"handFuncB"}

Matching rules

Since the Gin route is used httprouter, and httprouter the path matching rules are arranged as follows:

/path

This type of path will only match /path.

It will not match /path/.

  • Start the service
func  main () {
	 // Create a default routing engine 
	engine := gin.Default()
	 // Register routing 
	engine . GET ("/test", func(context  * gin. Context ) {
		 context.JSON (200 , gin.H {
			 "msg" : "success",
		})
		return
	})
	_ = engine.Run(":9090")
}
  • Initiate a request
# will match
$ curl -X GET http://127.0.0.1:9090/test
{ "msg" : "success" }
# The command line request is returned, and the browser request will return normally 
$   ~ curl -X GET http://127.0.0.1:9090/test/
<a href="/test"> Moved Permanently </a>

When the registered routing path is: /path, it will not match /path/, and it will be returned when requested with a command Moved Permanently, but it will be returned normally when requested with a browser. Reason: httprouter Automatic redirection is enabled by default and /path/ will be redirected to /path.

:param

:param: are the names of the parameters.

  • Matching rules
Routing Rules Request Examples Parameter Values ​​
/path/:a /test/finbarrs a=finbarrs
/path/:a/:b /test/finbarrs/1 a=finbarrs,b=1
/path/:a/:b/:c /test/finbarrs/1/2 a=finbarrs,b=1,c=2
  • Start the service
package main

import (
	 "github.com/gin-gonic/gin"  // Import Gin framework
)

func  main () {
	 // Create a default routing engine 
	engine := gin.Default()
	 // Register routing 
	engine . GET ( "/test/:name" , func(context * gin.Context) {
		 // Receive parameters 
		name := context.Param("name")
		 context.JSON(200, gin.H{"msg": "success", "name": name})
	})
	engine.GET("/test/:name/:age", func(context *gin.Context) {
		// receive parameters
		name := context.Param("name")
		age := context.Param("age")
		context.JSON(200, gin.H{
			"msg": "success",
			"name": name,
			"phone":age,
		})
	})
	engine.GET("/test/:name/:age/:height", func(context *gin.Context) {
		// receive parameters
		name := context.Param("name")
		age := context.Param("age")
		height := context.Param("height")
		context.JSON(200, gin.H{
			"msg": "success",
			"name": name,
			"phone":age,
			"height":height,
		})
	})
	_ = engine.Run(":9090")
}
  • Initiate requests
$ curl -X GET http://127.0.0.1:9090/test/finbarrs
{"msg":"success","name":"finbarrs"}
$ curl -X GET http://127.0.0.1:9090/test/finbarrs/18
{"msg":"success","name":"finbarrs","phone":"18"}
$ curl -X GET http://127.0.0.1:9090/test/finbarrs/18/170
{"height":"170","msg":"success","name":"finbarrs","phone":"18"}

*param

Matches from the specified position (including the prefix "/") to the end.

  • Matching rules
Routing Rules Request Examples Parameter Values ​​
/path/*a /test/finbarrs a=/finbarrs
  /test/finbarrs/1 a=finbarrs/1
  /test/finbarrs/1/2 a=finbarrs/1/2
  • Start the service
package main

import (
	"github.com/gin-gonic/gin" // Introduce Gin framework
)

func main() {
	// Create a default routing engine
	engine := gin.Default()
	// register route
	engine.GET("/test/*param", func(context *gin.Context) {
		// receive parameters
		param := context.Param("param")
		context.JSON(200, gin.H{"msg": "success", "name": param})
	})
	_ = engine.Run(":9090")
}
  • Initiate requests
$ curl -X GET http://127.0.0.1:9090/test/finbarrs
{"msg":"success","name":"/finbarrs"}
$ curl -X GET http://127.0.0.1:9090/test/finbarrs/1
{"msg":"success","name":"/finbarrs/1"}
$ curl -X GET http://127.0.0.1:9090/test/finbarrs/1/2
{"msg":"success","name":"/finbarrs/1/2"}