对于路由分组,兔兔在这一章中,定义的路由分组结构体如下
RouterGroup struct {
prefix string
middlewares []HandlerFunc // support middleware
parent *RouterGroup // support nesting
engine *Engine // all groups share a Engine instance
}
目前我们还没到中间件等AOP操作的实现,所以本文就没有将middlewares字段加上。就当前这个阶段,middlewares字段加上没什么用。
具体代码看Github
完整框架看Github
路由分组
关于路由分组的好处,我这就不细说了,对于这个功能,其实可以没有的,只是为了方便用户使用,我们额外加上这个功能
具体看下Gin框架的路由风分组如何使用的
package main
import "github.com/gin-gonic/gin"
func main() {
r := gin.Default()
r.Group("v1")
{
r.GET("/user", func(ctx *gin.Context) {})
r.GET("/order", func(ctx *gin.Context) {})
}
// http://localhost:8080/v1/user
// http://localhost:8080/v1/order
r.Run(":8080")
}
我们想实现的效果
- engine能够能够调用
Group方法实现分组 GET、POST、PUT、DELETE等衍生API转移到RouterGroup中实现addRouter方法转移到RouterGroup中实现,统一和路由树沟通
通过上述的分析,得出结论,RouterGroup结构体字段如下
type RouterGroup struct {
prefix string // 前缀
parent *RouterGroup // 父路由组
engine *Engine // 对于这个属性,完全是为了从Engine中能够拿到路由树信息并注册和匹配路由
}
通过上述的分析,得出结论,Engine结构更新如下
type Engine struct {
router *router // 路由树
*RouterGroup // 路由组
}
完成效果1
func (group *RouterGroup) Group(prefix string) *RouterGroup {
newGroup := &RouterGroup{
prefix: fmt.Sprintf("%s%s", group.prefix, prefix),
parent: group,
engine: group.engine,
}
return newGroup
}
完成效果2
// GET 外部衍生API,提供给用户使用,现在嫁接到RouterGroup上
func (group *RouterGroup) GET(pattern string, handlerFunc HandlerFunc) {
group.addRouter(http.MethodGet, pattern, handlerFunc)
}
func (group *RouterGroup) POST(pattern string, handlerFunc HandlerFunc) {
group.addRouter(http.MethodPost, pattern, handlerFunc)
}
func (group *RouterGroup) DELETE(pattern string, handlerFunc HandlerFunc) {
group.addRouter(http.MethodDelete, pattern, handlerFunc)
}
func (group *RouterGroup) PUT(pattern string, handlerFunc HandlerFunc) {
group.addRouter(http.MethodPut, pattern, handlerFunc)
}
完成效果3
// 在路由组上定义一个添加路由的方法,这个作为唯一和路由树交互的入口
func (group *RouterGroup) addRouter(method string, pattern string, handlerFunc HandlerFunc) {
pattern = fmt.Sprintf("%s%s", group.prefix, pattern)
log.Printf("Add Router %4s - %s", method, pattern)
group.engine.router.addRouter(method, pattern, handlerFunc)
}
上述完成测试
func main() {
engine := neo.New()
v1 := engine.Group("/v1")
{
v1.GET("/user", func(ctx *neo.Context) {
ctx.String(http.StatusOK, "v1/user")
})
v1.POST("/order", func(ctx *neo.Context) {
ctx.String(http.StatusOK, "v1/order")
})
v1.DELETE("/cart", func(ctx *neo.Context) {
ctx.String(http.StatusOK, "v1/cart")
})
v1.PUT("/admin", func(ctx *neo.Context) {
ctx.String(http.StatusOK, "v1/admin")
})
}
v2 := engine.Group("/v2")
{
v2.GET("/user", func(ctx *neo.Context) {
ctx.String(http.StatusOK, "v1/user")
})
v2.POST("/order", func(ctx *neo.Context) {
ctx.String(http.StatusOK, "v1/order")
})
v2.DELETE("/cart", func(ctx *neo.Context) {
ctx.String(http.StatusOK, "v1/cart")
})
v2.PUT("/admin", func(ctx *neo.Context) {
ctx.String(http.StatusOK, "v1/admin")
})
}
_ = engine.Run(":8080")
}