Gin routing resolution

Routing is the core function of web frameworks. Such routing is generally implemented: in accordance with the routing  / into the routing plurality of cutting string array, then follow the same route to the previous subarray configured tree structure; when addressed, the first request  url in accordance with  / segmentation, then traverse tree addressing.

For example: define two routes  /user/get, /user/deletewe will have to construct a three node's routing tree root node is the  usertwo child nodes respectively  get delete.

The above-described embodiment is an implementation of the routing tree, and intuitive and easy to understand. Url to be segmented, comparison, time complexity  O(2n).

Gin routing data structure implemented using a similar prefix tree, simply to traverse the string again, the time complexity is O(n).

Of course, once http requests, addressing this route optimization can be ignored.

Engine

Engine is the most important data structures Gin frame, that is the entry frame. We define the service routing information Engine objects assembled plug-in, run the service. As Engine in Chinese means "engine" as it is the framework of the core engine, the entire Web services are driven by it.

Engine is a precision instrument structure is very complicated, but the Engine object is very simple, because the most important part of the engine - the underlying HTTP server using the Go language built-in http server, nature Engine only the built-in HTTP server package, so it is more convenient to use.

Gin The  Engine structure embedded  RouterGroup structure defined  GET, POST such as the route registration method.

Engine The  trees field defines routing logic. trees Is a  methodTrees type (in fact  []methodTree), trees is an array, different routing request method (in different trees methodTree) in.

Finally, methodTree in  root field ( *nodetype) is the root of the routing tree. And the address tree structure are in  *nodethe finished process.

FIG UML structure
FIG engine structure

trees Is an array, the array will have different request method of routing tree.

tree structure

node

node structure is defined as follows

type node struct {
    path      string           // 当前节点相对路径(与祖先节点的 path 拼接可得到完整路径) indices string // 所以孩子节点的path[0]组成的字符串 children []*node // 孩子节点 handlers HandlersChain // 当前节点的处理函数(包括中间件) priority uint32 // 当前节点及子孙节点的实际路由数量 nType nodeType // 节点类型 maxParams uint8 // 子孙节点的最大参数数量 wildChild bool // 孩子节点是否有通配符(wildcard) }

path and indices

On  path and  indices, in fact, it is the use of logic prefix tree.

For chestnut:
If we have two routes, namely  /index, /interthe head node for the  {path: "/in", indices: "dt"...}two child nodes{path: "dex", indices: ""},{path: "ter", indices: ""}

handlers

handlersCorresponding to the node is stored in all the functions in the routing process, when dealing with business logic is such that:

func (c *Context) Next() { c.index++ for s := int8(len(c.handlers)); c.index < s; c.index++ { c.handlers[c.index](c) } }

In general, except for the last function, the function is called middleware foregoing.

If a node  handlersis empty, it indicates that the corresponding routing node does not exist. For example root node corresponds to the routing defined above  /in does not exist, it  handlersis [].

nType

Gin defined four types of nodes:

const (
    static nodeType = iota // 普通节点,默认
    root       // 根节点 param // 参数路由,比如 /user/:id catchAll // 匹配所有内容的路由,比如 /article/*key )

param The  catchAll difference is the use of  : the  * difference. * Everything after will be assigned to routing parameters  key; but  : can be used multiple times.
For example: /user/:id/:no it is legal, but it  /user/*id/:no is illegal, because  * behind all content will be assigned to the parameter  id.

wildChild

If the child node is a wildcard character ( *or :), then the field is  true.

Examples of a routing tree

Define the route as follows:

r.GET("/", func(context *gin.Context) {}) r.GET("/index", func(context *gin.Context) {}) r.GET("/inter", func(context *gin.Context) {}) r.GET("/go", func(context *gin.Context) {}) r.GET("/game/:id/:k", func(context *gin.Context) {})

The resulting routing tree Pictured:
Road with trees

Guess you like

Origin www.cnblogs.com/linguoguo/p/12148124.html