Gin路由之routes group

2023-10-30 18:01:23 浏览数 (2)

使用gin框架开发的时候,为了设计符合restful的接口,就得想办法使用一些比较规范容易使用的路由,今天就来介绍一下为了管理相同url的routes group。

gin框架中采用的路由库是基于httprouter做的,地址

代码语言:javascript复制
https://github.com/julienschmidt/httprouter来个hello world先
package main
import (
    "net/http"
"github.com/gin-gonic/gin"
#导入网络库和gin框架
)
func main() {
    r := gin.Default()
    r.GET("/", func(c *gin.Context) {
        c.String(http.StatusOK, "hello word")
    })
    r.POST("/xxxpost",getting)
    r.PUT("/xxxput")
    //监听端口默认为8080
    r.Run(":8888")
}

开发定义路由的时候,肯定避免不了很多部分重复的路由,gin提供了routes group。其他文档上说是为了管理一些相同的url,也就是说变得模块化,同一个业务之下的方法管理也会更容易,清楚,将同样的模块放在一起,相同版本的api放在一起,在gin框架叫分组路由。使用这个方法就可以生成一个分组,用此注册不同路由。

代码语言:javascript复制
package main
import (
       "fmt"
       "github.com/gin-gonic/gin"
)
func main() {
       // 1.创建路由
       r := gin.Default()
       // 路由组v1 ,处理GET请求
       v1 := r.Group("/v1/cillian/")
       // {} 是书写规范
       {
              v1.GET("/login", login)
              v1.GET("submit", submit)
       }
       // 路由组v2 ,处理POST请求
       v2 := r.Group("/v2/cillian/")
       {
              v2.POST("/login", login)
              v2.POST("/submit", submit)
       }
       r.Run(":8888")
}
func login(c *gin.Context) {
       name := c.DefaultQuery("name", "cillian")
       c.String(200, fmt.Sprintf("hello %sn", name))
}
func submit(c *gin.Context) {
       name := c.DefaultQuery("name", "cillian")
       c.String(200, fmt.Sprintf("hello %sn", name))
}

看到方法定义,是可以接受两个参数,一个就是注册的分组路由(命名空间),第二个就是对应的调用函数。

调用接口试一下,发送get请求,默认返回hello cillian。

如果使用post呢

改成正确的post地址如下:

代码语言:javascript复制
func (group *RouterGroup) GET(relativePath string, handlers ...HandlerFunc) IRoutes {
    return group.handle("GET", relativePath, handlers)
}
这里第一个参数relativePath,是一个传给gin的一个相对路径,传给谁?
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()
}
absolutePath := group.calculateAbsolutePath(relativePath)通过代码,我们可以看出是相对当前的这个group。再看看生成分组路由的方法:
func (group *RouterGroup) Group(relativePath string, handlers ...HandlerFunc) *RouterGroup {
    return &RouterGroup{
        Handlers: group.combineHandlers(handlers),
        basePath: group.calculateAbsolutePath(relativePath),
        engine:   group.engine,
    }

}
这里通过gin.Default()生成的gin.Engine包含一个RouterGroup
(嵌套组合),所以它可以用RouterGroup的方法。group方法有生成一个*RouterGroup
func (group *RouterGroup) calculateAbsolutePath(relativePath string) string {
    return joinPaths(group.basePath, relativePath)
}

一个基于当前RouterGroup的basePath的路径拼接,所以我们通过Group方法改变新生成RouterGroup中的basePath,就达到了路由分组的目的。同时因为多次调用Group

方法,都是基于上一个RouterGroup的basePath拼接成下一个RouterGroup的basePath,也就达到了路由分组嵌套的目的。我们通过gin.Default()生成的最初的gin.Engine,对应的basePath是/根节点。

到这也明白gin框架中分组路由的功能是非常强大的,一个是版本升级、模块的划分、而且实现也很简单。所以抓紧去实践吧,祝学习顺利!

END

作者|希里安

0 人点赞