Gin路由之routes group

625 阅读3分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第2天

作者按:

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

1、gin基本路由

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

github.com/julienschmi…

来个hello world先

package main

import (

"net/http"

"github.com/gin-gonic/g…"

#导入网络库和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")

}

2、routes group

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

package main

import (

"fmt"

"github.com/gin-gonic/g…"

)

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 %s\n", name))

}

func submit(c *gin.Context) {

name := c.DefaultQuery("name", "cillian")

c.String(200, fmt.Sprintf("hello %s\n", name))

}

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

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

如果使用post呢

改成正确的post地址

看一下源代码:

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框架中分组路由的功能是非常强大的,一个是版本升级、模块的划分、而且实现也很简单。所以抓紧去实践吧,祝学习顺利!