在本节,最终的代码目录结构如下:
1 2 3 4 5 6 7 8
| dain/ |--context.go |--dain.go |--router.go |--trie.go |--go.mod main.go go.mod
|
实现目标
可以对路由进行分组,每一组内的路由都可以有相似用途,也对分组定义中间件。
main.go
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| package main
import ( "DawnGin/dain" "net/http" )
func main() { e := dain.New()
v1 := e.Group("/v1") { v1.Get("/video/:name", func(c *dain.Context) { videoName := c.Param("name") c.String(http.StatusOK, "Hello, this is v1 group, video name = %v, path = %v", videoName, c.Path) }) }
e.Run(":9000") }
|
分组控制
dain/dain.go
结构体
我们需要通过前缀来区分分组路由,同时还需要记录当前分组的上一层、应用于当前分组的中间件以及最顶层的 Engine:
1 2 3 4 5 6 7
| type RouterGroup struct { prefix string parent *RouterGroup middleware []HandlerFunc engine *Engine }
|
可以将 Engine 作为最顶层的分组,也就是说 Engine 具有 RouterGroup 的所有能力:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| type Engine struct { router *router *RouterGroup groups []*RouterGroup }
func New() *Engine { engine := &Engine{router: NewRouter()} engine.RouterGroup = &RouterGroup{engine: engine} engine.groups = []*RouterGroup{engine.RouterGroup}
return engine }
|
添加分组
通过 Group 函数可以添加分组:
1 2 3 4 5 6 7 8 9 10
| 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 }
|
注册路由
因为分组也可以注册路由,所以将 Engine 的路由注册方法更改为 RouterGroup 的方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| func (group *RouterGroup) addRouter(method, pattern string, handler HandlerFunc) { pattern = group.prefix + pattern group.engine.router.addRouter(method, pattern, handler) }
func (group *RouterGroup) Get(pattern string, handler HandlerFunc) { group.addRouter("GET", pattern, handler) }
func (group *RouterGroup) Post(pattern string, handler HandlerFunc) { group.addRouter("POST", pattern, handler) }
|