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/delete
we will have to construct a three node's routing tree root node is the user
two 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 ( *node
type) is the root of the routing tree. And the address tree structure are in *node
the finished process.
FIG UML structure
trees
Is an array, the array will have different request method of routing tree.
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
, /inter
the head node for the {path: "/in", indices: "dt"...}
two child nodes{path: "dex", indices: ""},{path: "ter", indices: ""}
handlers
handlers
Corresponding 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 handlers
is 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 handlers
is []
.
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: