手把手和你一起实现一个Web框架实战——EzWeb框架(四)[Go语言笔记]Go项目实战

手把手和你一起实现一个Web框架实战——EzWeb框架(四)[Go语言笔记]Go项目实战

代码仓库:

github

gitee

中文注释,非常详尽,可以配合食用

这一篇文章主要实现路由组功能。实现路由组对路由进行更便利的管理,如应用中间件的应用。

一、路由组设计

手把手和你一起实现一个Web框架实战——EzWeb框架(四)[Go语言笔记]Go项目实战

这里进行的设计是以路由组前缀来进行区分的。嵌套

实现一个r.Group(prefix string)函数来构造路由组,使之在调用GETPOST等方法进行路由注册时,拥有共同的前缀。GETPOST等方法注册路由时调用了addRoute()方法,即如果我们在路由组中做注册路由的方法时,我们注册的路由是"Group.prefixt+last(这里的last是路由组内注册方法的路径)"。

type RouterGroup struct {
prefix string
middlewares []HandlerFunc // 用于存储分组的中间件
engine *Engine // 这里实现的嵌套让其拥有了engine的全部属性,所有的分组都使用了Engine实例,可以通过engine间接的访问各种接口
} // Engine 实现了"net/http"标准库中的 Handler 接口中的ServeHTTP方法
type Engine struct {
*RouterGroup //嵌套,让Engine拥有RouterGroup的全部属性,这样做体现在我们使用r.Group()创建路由组的时候
groups []*RouterGroup
//用于存储路由处理方法
//key是方法类型加路径,value是用户的处理方法
router *router
}

当我们调用r.Group(prefix string),我们就构建了一个RouterGroup实例

engine *Engine

这让它们拥有一个共同的处理实例engine,当调用addGroup方法,为某个路由组路由注册时,我们可以通过先对"路由组前缀+剩余path",这样的处理,再通过调用group.engine.router.addRoute(method, path, handler)进行路由注册。

func (group *RouterGroup) addRoute(method string, last string, handler HandlerFunc) {
path := group.prefix + last
group.engine.router.addRoute(method, path, handler)
}

二、方法修改

这里体现了为什么在RouterGroup结构体中要嵌套一个engine *Engine。我们在使用这个路由组功能的demo是这样的。

r := Ez.New()
api := r.Group("/api")
{
api.POST("/hello", func(c *Ez.Context) {
c.JSON(http.StatusOK,Ez.H{
"message" : "hello",
})
})
}

r是一个Engine指针变量,我们的Group()方法,是属于RouterGroup的,在Engine结构体中嵌套了*RouterGroup使得我们可以直接调用它。而我们通过r.Group("/api")创建的这个api变量是一个Routergroup指针变量,我们们想要使用api.POST注册路由的时候,我们在Routergroup结构体中嵌套的engine *Engine就起了相关的作用。

// New Engine
func New() *Engine {
//新建一个engine实例
engine := &Engine{router: newRouter()}
engine.RouterGroup = &RouterGroup{engine: engine}
engine.groups = []*RouterGroup{engine.RouterGroup}
return engine
}
// Group 新建Group
func (group *RouterGroup) Group(prefix string) *RouterGroup {
engine := group.engine
newGroup := &RouterGroup{
prefix: group.prefix + prefix, //前缀
engine: engine, //任何路由组都共享一个处理实例
}
engine.groups = append(engine.groups, newGroup)
return newGroup
}
// engine.router.addRoute 方法封装在router中
func (group *RouterGroup) addRoute(method string, last string, handler HandlerFunc) {
path := group.prefix + last
group.engine.router.addRoute(method, path, handler)
}
func (group *RouterGroup) GET(path string, handler HandlerFunc) {
group.addRoute("GET", path, handler)
} func (group *RouterGroup) POST(path string, handler HandlerFunc) {
group.addRoute("POST", path, handler)
}

demo测试:

/*
@Time : 2021/8/16 下午4:01
@Author : mrxuexi
@File : main
@Software: GoLand
*/
package main import (
"Ez"
"net/http"
)
func main() {
r := Ez.New() api := r.Group("/api")
{
api.POST("/hello", func(c *Ez.Context) {
c.JSON(http.StatusOK,Ez.H{
"message" : "hello",
})
})
api.GET("/login", func(c *Ez.Context) {
c.JSON(200,Ez.H{
"name" : c.PostForm("name"),
})
})
} r.Run(":9090")
}

手把手和你一起实现一个Web框架实战——EzWeb框架(四)[Go语言笔记]Go项目实战

成功!

手把手和你一起实现一个Web框架实战——EzWeb框架(四)[Go语言笔记]Go项目实战

参考:

[1]: https://github.com/geektutu/7days-golang/tree/master/gee-web ""gee""

[2]: https://github.com/gin-gonic/gin ""gin""

上一篇:non-manifold Mesh(非流形网格)


下一篇:拿到List>对用属性的值。。。。。。。