174 lines
4.8 KiB
Go
174 lines
4.8 KiB
Go
package web
|
||
|
||
import "fmt"
|
||
|
||
type routerInterface interface {
|
||
routeGroupInterface
|
||
Run(addr string) error
|
||
}
|
||
|
||
type Engine struct {
|
||
Addr string
|
||
newContextFun func() Context
|
||
DirectRoutes map[string]*RouteDescInfo
|
||
GroupRoutes map[string]*Group
|
||
coreRouter routerInterface
|
||
}
|
||
|
||
// NewEngine 使用gin或者iris创建web引擎,newContextFun为调用方需要实现的context初始化函数
|
||
// coreRouter指定不同web引擎,目前只支持gin
|
||
func NewEngine(coreRouter string, newContextFun func() Context) *Engine {
|
||
e := &Engine{
|
||
newContextFun: newContextFun,
|
||
DirectRoutes: make(map[string]*RouteDescInfo),
|
||
GroupRoutes: make(map[string]*Group),
|
||
}
|
||
switch coreRouter {
|
||
//case "iris":
|
||
// e.coreRouter = newRouterIris(newContextFun)
|
||
case "gin":
|
||
e.coreRouter = newRouterGin(newContextFun)
|
||
default:
|
||
panic(fmt.Errorf("NewEngine only support irir or gin, invalid type:%v", coreRouter))
|
||
}
|
||
return e
|
||
}
|
||
|
||
func (e *Engine) Use(middlewares ...HandlerFunc) {
|
||
e.coreRouter.Use(middlewares...)
|
||
}
|
||
|
||
func (e *Engine) Group(path string, handlers ...HandlerFunc) *Group {
|
||
path = pathBeTheSame(path)
|
||
routeGroup := e.coreRouter.Group(path, handlers...)
|
||
group := newGroup(routeGroup)
|
||
e.GroupRoutes[path] = group
|
||
return group
|
||
}
|
||
|
||
// Get 注册get方法路由,根据request请求体优先从body中以json格式解析参数,如果没有body,则从uri参数中解析出请求参数
|
||
//
|
||
// path:路径
|
||
// desc:路由的一个简短描述
|
||
// request:请求结构体
|
||
// 格式:
|
||
// type struct {
|
||
// F1 int `json:"f1" desc:"字段描述" default:"234" required:"true"`
|
||
// }
|
||
// tag描述:
|
||
// json:字段名
|
||
// desc:字段简短描述,没有可以不写
|
||
// default:默认值,没有可以不写
|
||
// required:是否必填字段,没有要求可以不写
|
||
// 注意,get、post注册的request结构字段,如果是uri参数方式类型只支持golang基础类型以及基础类型的切片,不能是结构体类型,
|
||
// 例如:
|
||
// type Field struct {
|
||
// A int
|
||
// B bool
|
||
// }
|
||
// type Request struct {
|
||
// F1 *Field
|
||
// }
|
||
// F1字段就是非法的,无法解析,会报错
|
||
// handlers:路由处理函数,如果没有请求体,就是func(ctx),否则就是func(ctx, request)
|
||
func (e *Engine) Get(path string, desc string, access AccessMode, request any, handler HandlerFunc) {
|
||
path = pathBeTheSame(path)
|
||
old, find := e.DirectRoutes[path]
|
||
if !find {
|
||
e.DirectRoutes[path] = newRouteDescInfo(path, desc, "GET", access, request)
|
||
} else {
|
||
old.Method = append(old.Method, "GET")
|
||
e.DirectRoutes[path] = old
|
||
}
|
||
e.coreRouter.Get(path, desc, request, handler)
|
||
}
|
||
|
||
// Post 注册post方法路由,根据request请求体优先从body中以json格式解析参数,如果没有body,则从uri参数中解析出请求参数
|
||
//
|
||
// path:路径
|
||
// desc:路由的一个简短描述
|
||
// request:请求结构体
|
||
// 格式:
|
||
// type struct {
|
||
// F1 int `json:"f1" desc:"字段描述" default:"234" required:"true"`
|
||
// }
|
||
// tag描述:
|
||
// json:字段名
|
||
// desc:字段简短描述,没有可以不写
|
||
// default:默认值,没有可以不写
|
||
// required:是否必填字段,没有要求可以不写
|
||
// 注意,get、post注册的request结构字段,如果是uri参数方式类型只支持golang基础类型以及基础类型的切片,不能是结构体类型,
|
||
// 例如:
|
||
// type Field struct {
|
||
// A int
|
||
// B bool
|
||
// }
|
||
// type Request struct {
|
||
// F1 *Field
|
||
// }
|
||
// F1字段就是非法的,无法解析,会报错
|
||
// handlers:路由处理函数,如果没有请求体,就是func(ctx),否则就是func(ctx, request)
|
||
func (e *Engine) Post(path, desc string, access AccessMode, request any, handler HandlerFunc) {
|
||
path = pathBeTheSame(path)
|
||
old, find := e.DirectRoutes[path]
|
||
if !find {
|
||
e.DirectRoutes[path] = newRouteDescInfo(path, desc, "POST", access, request)
|
||
} else {
|
||
old.Method = append(old.Method, "POST")
|
||
e.DirectRoutes[path] = old
|
||
}
|
||
e.coreRouter.Post(path, desc, request, handler)
|
||
}
|
||
|
||
func (e *Engine) Run(addr string) error {
|
||
e.Addr = addr
|
||
return e.coreRouter.Run(addr)
|
||
}
|
||
|
||
// TravelPathTree 获取所有路径的描述表
|
||
func (e *Engine) TravelPathTree() map[string]*RouteDescInfo {
|
||
m := make(map[string]*RouteDescInfo)
|
||
for k, route := range e.DirectRoutes {
|
||
m[k] = route
|
||
}
|
||
for k, subG := range e.GroupRoutes {
|
||
gm := subG.TravelPathTree()
|
||
for k1, v1 := range gm {
|
||
m[k+k1] = v1
|
||
}
|
||
}
|
||
return m
|
||
}
|
||
|
||
func pathBeTheSame(path string) string {
|
||
if path == "" {
|
||
return ""
|
||
}
|
||
if path == "/" {
|
||
return path
|
||
}
|
||
if path[0] != '/' {
|
||
path = "/" + path
|
||
}
|
||
if path[len(path)-1] == '/' {
|
||
path = path[:len(path)-1]
|
||
}
|
||
return path
|
||
}
|
||
|
||
func pathBeTheSame1(path string) string {
|
||
if path == "" {
|
||
return ""
|
||
}
|
||
if path == "/" {
|
||
return path
|
||
}
|
||
if path[0] != '/' {
|
||
path = "/" + path
|
||
}
|
||
if path[len(path)-1] == '/' {
|
||
path = path[:len(path)-1]
|
||
}
|
||
return path
|
||
}
|