用golang写gee(day4)

目录

项目地址:https://geektutu.com/post/gee-day4.html

目标

这次要完成http的分组功能,简而言之,就是对于一些具有共同前缀的资源,我们可以通过哦Group()来一起注册,且可以嵌入中间件,使得这些资源都有相同的特性。最终使用效果如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
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")
}

可以看得出来,这样实现会比较简洁漂亮。也可以使用嵌套和中间件。

实现

定义RouterGroup类型,Engine本身就是一个RouterGroup,而所有的RouterGroup都指向一个Engine

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
RouterGroup struct {  
	prefix      string  
	middlewares []HandlerFunc // support middleware  
	parent      *RouterGroup  // support nesting  
	engine      *Engine       // all groups share a Engine instance  
}

Engine struct {  
	*RouterGroup  
	router *router  
	groups []*RouterGroup // store all groups  
}

留意Engine在初始化时,Groups只包含它自身的RouterGroup。将原来为Engine实现的GET等方法,改为为RouterGroup的,此时Engine也可以隐性调用这些成员函数。这样就可以偷龙转凤一般,实现这种效果:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
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)
	})
}

说白了,现在就是加了个前缀功能而已。Grouping真正的威力要在中间件中体现出来吧?

0%