【Gee-Web框架】【Day4】【Golang】分组控制

  1. 实现路由分组控制Route Group Control

一、 分组的意义

1. 简要说明

  • 分组控制Group Control是Web框架应提供的基础功能之一
  • 所谓分组,是指路由的分组
  • 如果没有路由分组,我们需要针对每一个路由进行控制,但在真实的业务场景中,往往某一组路由需要相似的处理,例如:
    • 以/post开头的路由匿名可访问
    • 以/admin开头的路由需要鉴权
    • 以/api开头的路由是RESTful接口,可以对接第三方平台,需要三方平台鉴权
  • 大部分情况下的路由分组,是以相同的前缀来区分的
  • 中间件可以给框架提供无限的扩展能力,应用在分组上,可以使得分组控制的收益更为明显,而不是共享相同的路由前缀这么简单
  • 一个Group对象需要具备哪些属性呢?首先是前缀prefix,比如/或者/api
  • 要支持分组嵌套,需要知道当前分组的父亲parent是谁
  • 中间件是应用在分组上的,还需要存储应用在该分组上的中间件middlewares
  • Group对象,还需要有访问Router的能力,为了方便,我们可以在Group中,保存一个指针,指向Engine,整个框架的所有资源都是由Engine统一协调的,那么就可以通过Engine间接地访问各种接口了

2. 具体实现

  • gee.go
    // 将和路由有关的函数,都交给RouterGroup实现
    type RouterGroup struct{
    	prefix string
    	middlewares []HandlerFunc
    	parent *RouterGroup
    	engine *Engine	
    }
    
    // 进一步抽象,将Engine作为最顶层的分组,也就是说Engine拥有RouterGroup所有的能力
    // 整个框架的所有资源都是由Engine统一协调
    // 通过Engine间接地访问各种接口
    type Engine struct{
    	*RouterGroup
    	router *router
    	groups []*RouterGroup	
    }
    	
    func New() *Engine{
    	engine := &Engine{router: newRouter()}
    	engine.RouterGroup = &RouterGroup{engine: engine}
    	engine.groups = []*RouterGroup{engine.RouterGroup}
    	return engine	
    }
    	
    func (group *RouterGroup) Group(prefix string) *RouterGroup{
    	engine := group.engine
    	newGroup := &RouteGroup{
    		prefix: group.prefix + prefix,
    		parent: group,
    		engine: engine,	
    	}	
    	engine.groups = append(engine.groups, newGroup)
    	return newGroup
    }
    
    // 调用了group.engine.router.addRoute来实现路由的映射
    // 由于Engine从某种意义上继承了RouteGroup的所有属性和方法
    // 这样既可以像之前一样添加路由,也可以通过分组添加路由
    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)	
    }
    	
    func (group *RouterGroup) GET(pattern string, handler HandlerFunc){
    	group.addRoute("GET", pattern, handler)	
    }
    
    func (group *RouterGroup) POST(pattern string, handler HandlerFunc){
    	group.addRoute("POST", pattern, handler)	
    }
    
  • main.go
    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){
    			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){
    			c.String(http.StatusOK, "hello %s, you're at %s\n", c.Parma("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")
    }
    
  • 测试
    • curl “http://localhost:9999/v1/hello?name=geektutu”
    • curl “http://localhost:9999/v2/hello/geektutu”

参考

  1. https://geektutu.com/post/gee-day4.html
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值