分组的意义
-
以
/post
开头的路由匿名可访问。 -
以
/admin
开头的路由需要鉴权。 -
以
/api
开头的路由是 RESTful 接口,可以对接第三方平台,需要三方平台鉴权。
我们通常是以相同的前缀来区分路由分组,而作用在分组上的中间件,都会作用在子分组
分组嵌套
-
首先要有一个前缀prefix
-
然后我们要知道分组的父亲是谁
-
中间件还需要再分组上
-
Group需要直接映射路由规则和Handler,所以说Group其实需要与Engine相互关联
r := gee.New()
v1 := r.Group("/v1")
v1.GET("/", func(c *gee.Context) {
c.HTML(http.StatusOK, "<h1>Hello Gee</h1>")
})
最后Group的定义:
RouterGroup struct {
prefix string
middlewares []HandlerFunc // support middleware
parent *RouterGroup // support nesting
engine *Engine // all groups share a Engine instance
}
然后这里就将Engine作为最顶层的分组了,Engine拥有RouteGroup所有的能力
Engine struct {
*RouterGroup//匿名结构体,可以使用RouteGroup中的所有方法和字段(不包括私有)
router *router
groups []*RouterGroup // store all groups
}
我们将和路由有关的函数交给RouteGroup处理
// New is the constructor of gee.Engine
func New() *Engine {
engine := &Engine{router: newRouter()}
engine.RouterGroup = &RouterGroup{engine: engine}
engine.groups = []*RouterGroup{engine.RouterGroup}
return engine
}
// Group is defined to create a new RouterGroup
// remember all groups share the same Engine instance
func (group *RouterGroup) Group(prefix string) *RouterGroup {
engine := group.engine
newGroup := &RouterGroup{
prefix: group.prefix + prefix,
parent: group,
engine: engine,
}
engine.groups = append(engine.groups, newGroup)
return newGroup
}
func (group *RouterGroup) addRoute(method string, comp string, handler HandlerFunc) {
pattern := group.prefix + comp
log.Printf("Route %4s - %s", method, pattern)
group.engine.router.addRoute(method, pattern, handler)
}
// GET defines the method to add GET request
func (group *RouterGroup) GET(pattern string, handler HandlerFunc) {
group.addRoute("GET", pattern, handler)
}
// POST defines the method to add POST request
func (group *RouterGroup) POST(pattern string, handler HandlerFunc) {
group.addRoute("POST", pattern, handler)
}
我们这样做的目的是我们可以像原来一样,通过Engine添加路由规则和方法,然后Group也可以添加路由和方法
测试Demo
func main() {
r := gee.New()
r.GET("/index", func(c *gee.Context) {
c.HTML(http.StatusOK, "<h1>Index Page</h1>")
})
v1 := r.Group("/v1")
{
v1.GET("/", func(c *gee.Context) {
c.HTML(http.StatusOK, "<h1>Hello Gee</h1>")
})
v1.GET("/hello", func(c *gee.Context) {
// expect /hello?name=geektutu
c.String(http.StatusOK, "hello %s, you're at %s\n", c.Query("name"), c.Path)
})
}
v2 := r.Group("/v2")
{
v2.GET("/hello/:name", func(c *gee.Context) {
// expect /hello/geektutu
c.String(http.StatusOK, "hello %s, you're at %s\n", c.Param("name"), c.Path)
})
v2.POST("/login", func(c *gee.Context) {
c.JSON(http.StatusOK, gee.H{
"username": c.PostForm("username"),
"password": c.PostForm("password"),
})
})
}
r.Run(":9999")
}
唯一要注意的就是go.mod注意那个名称,我们不是已经新建了几个mod了嘛,在每一天下面,注意mod的名称
module example2
每次的moule的名称要不一样啊