手把手和你一起實現一個Web框架實戰——EzWeb框架(四)[Go語言筆記]Go項目實戰
代碼倉庫:
github
gitee
中文注釋,非常詳盡,可以配合食用
本篇代碼,請選擇demo4
這一篇文章主要實現路由組功能。實現路由組對路由進行更便利的管理,如應用中間件的應用。
一、路由組設計
這里進行的設計是以路由組前綴來進行區分的。嵌套
實現一個r.Group(prefix string)
函數來構造路由組,使之在調用GET
、POST
等方法進行路由注冊時,擁有共同的前綴。GET
、POST
等方法注冊路由時調用了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")
}
成功!
參考:
[1]: https://github.com/geektutu/7days-golang/tree/master/gee-web ""gee""
[2]: https://github.com/gin-gonic/gin ""gin""