跳至主要內容
  • Hostloc 空間訪問刷分
  • 售賣場
  • 廣告位
  • 賣站?

4563博客

全新的繁體中文 WordPress 網站
  • 首頁
  • golang gin 框架分组路由的原理
未分類
21 3 月 2021

golang gin 框架分组路由的原理

golang gin 框架分组路由的原理

資深大佬 : liulei281 1

gin 文档中的一个例子

func main() {  router := gin.Default()   // Simple group: v1  v1 := router.Group("/v1")  {   v1.POST("/login", loginEndpoint)   v1.POST("/submit", submitEndpoint)   v1.POST("/read", readEndpoint)  }   // Simple group: v2  v2 := router.Group("/v2")  {   v2.POST("/login", loginEndpoint)   v2.POST("/submit", submitEndpoint)   v2.POST("/read", readEndpoint)  }   router.Run(":8080") } 

router.Group方法源码是这样的:

// Group creates a new router group. You should add all the routes that have common middlewares or the same path prefix. // For example, all the routes that use a common middleware for authorization could be grouped. func (group *RouterGroup) Group(relativePath string, handlers ...HandlerFunc) *RouterGroup {  return &RouterGroup{   Handlers: group.combineHandlers(handlers),   basePath: group.calculateAbsolutePath(relativePath),   engine:   group.engine,  } } 

从上面的例子看, v1 := router.Group("/v1")创建一个子分组v1, 并且v1.engine中存储了父级的信息, 这时候v1知道它的父级是router. 但是程序的入口是router, 但好像并没有把v1关联给router, 那么router怎么知道v1的存在?

(初学 golang, 请大佬解惑, 谢谢)

大佬有話說 (6)

  • 資深大佬 : abersheeran

    我纯 Golang 路人。但是 Gin 用的 Router 是基于 httprouter 的,httprouter 用的是 Radix Tree 。所以一定有一步是把节点加入树里。你再看看源码吧。

  • 資深大佬 : 676529483

    router 就是 Engine 对象,源码里面你看不是有 engine: group.engine 吗?

  • 資深大佬 : xxjwxc

    https://github.com/xxjwxc/ginrpc
    推荐这个

  • 資深大佬 : catror

    v1.POST() 和 v2.POST() 才是真正注册 route 的方法,group 只是方便理解和操作

  • 資深大佬 : cyjme

    那么 router 怎么知道 v1 的存在?

    =======

    // Group creates a new router group. You should add all the routes that have common middlewares or the same path prefix.
    // For example, all the routes that use a common middleware for authorization could be grouped.
    func (group *RouterGroup) Group(relativePath string, handlers …HandlerFunc) *RouterGroup {
    return &RouterGroup{
    Handlers: group.combineHandlers(handlers),
    basePath: group.calculateAbsolutePath(relativePath),
    engine: group.engine,
    }
    }

    源码中把 /v1 用于了 basePath 。

    然后从 router.GET() 这个方法开始看,看什么时候用到 basePath (也就是 /v1 )

    // GET is a shortcut for router.Handle(“GET”, path, handle).
    func (group *RouterGroup) GET(relativePath string, handlers …HandlerFunc) IRoutes {
    return group.handle( http.MethodGet, relativePath, handlers) //进入
    }

    func (group *RouterGroup) handle( httpMethod, relativePath string, handlers HandlersChain) IRoutes {
    absolutePath := group.calculateAbsolutePath(relativePath) //进入
    handlers = group.combineHandlers(handlers)
    group.engine.addRoute( httpMethod, absolutePath, handlers)
    return group.returnObj()
    }

    func (group *RouterGroup) calculateAbsolutePath(relativePath string) string {
    return joinPaths(group.basePath, relativePath) //这里的 basePath 就是你的 “/v1″,如果涉及到多重 group,可能是 /xxx/v1
    }

    =================
    上面应该解答了你的疑问『怎么知道 v1 存在』,在每一次 GET/POST 执行的时候,都会根据之前的 basePath 进行计算。

    继续深入,可以看 addRoute() —-> engine.trees 相关。然后就是 1 说的 httprouter tree 相关,如何快速查找匹配路由。

  • 主 資深大佬 : liulei281

    @catror
    @cyjme
    谢谢, 明白怎么回事了.

文章導覽

上一篇文章
下一篇文章

AD

其他操作

  • 登入
  • 訂閱網站內容的資訊提供
  • 訂閱留言的資訊提供
  • WordPress.org 台灣繁體中文

51la

4563博客

全新的繁體中文 WordPress 網站
返回頂端
本站採用 WordPress 建置 | 佈景主題採用 GretaThemes 所設計的 Memory
4563博客
  • Hostloc 空間訪問刷分
  • 售賣場
  • 廣告位
  • 賣站?
在這裡新增小工具