使用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
作者|希里安