一、概述
很多人都熟悉gin框架,但是很多人並沒有更深層次的挖掘gin的路由設計。web框架的核心是什麼?一個就是路由,所以想更深的瞭解這個框架,首先就要去深入瞭解gin框架的路由。
二、源碼
2.1 Engine結構體
type Engine struct {
RouterGroup //定義了 GET,POST 等路由註冊方法
...
trees methodTrees //路由邏輯
...
}
2.2 trees
type methodTrees []methodTree
type methodTree struct {
method string
root *node
}
type node struct {
path string //當前節點的相對路徑(與父節點的path拼接得到完成路徑)
indices string //所有孩子節點組成的字符串
wildChild bool //孩子節點是否存在通配符
nType nodeType //節點類型
priority uint32 //當前節點以及孫子節點的路由數量
children []*node //孫子節點
handlers HandlersChain //當前節點的處理函數(包括中間件)
fullPath string //原始path
}
通過上面的代碼結構,我們發現了什麼?我們看到了樹結構。實際gin框架的路由設計是前綴樹,如果不懂前綴樹的,可以去看下前綴樹的書籍。
三、node裏的數據說明
3.1 path和indices
使用的是前綴樹的邏輯,搜索引擎使用樹的結構比較多
舉例個例子說明:
如果我們存在2個路由。分別爲/demo,/deny,你覺得根節點和子節點如何劃分?
首先我們需要找到2個路由的共同點:de,indices就是子節點的字符串組合
- 根節點
path:de
indices:mn
- 子節點
path:mo
indices:
path:ny
indices:
3.2 handlers
handlers主要存儲的主要是這個節點所有需要實現的中間件相關的方法。具體處理邏輯可以自己看下源碼,這邊就不做介紹了。
3.3 nType
gin的節點類型:
const (
static nodeType = iota // 普通節點,默認
root // 根節點
param // 參數路由,比如 /demo/:test
catchAll // 匹配所有內容的路由,比如 /demo/*test
)
3.4 wildChild
如果孩子節點是通配符(*或者:),則該字段爲 true。