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 }