package app import ( "net/http" "git.yuntuo.hk/k2safe/go-omni/httpx" ) func (a *App) handle(routes httpx.RouterGroup, method, path string, handler httpx.Handler, middleware []httpx.Middleware) { routes.Handle(method, path, a.adapt(handler, middleware...)) } func (a *App) adapt(handler httpx.Handler, middleware ...httpx.Middleware) http.Handler { wrapped := handler all := make([]httpx.Middleware, 0, len(a.middlewares)+len(middleware)) all = append(all, a.middlewares...) all = append(all, middleware...) for index := len(all) - 1; index >= 0; index-- { if all[index] != nil { wrapped = all[index](wrapped) } } return http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) { requestContext := httpx.NewContext(request, writer, httpx.RouteParams(request.Context())) if err := wrapped(requestContext); err != nil { a.writeError(requestContext, err) } }) } // Handle registers an explicit method, including HEAD, OPTIONS and extension // methods, through the same business middleware and error handling as GET. func (a *App) Handle(method, path string, handler httpx.Handler, middleware ...httpx.Middleware) { a.handle(a.router, method, path, handler, middleware) } func (a *App) GET(path string, handler httpx.Handler, middleware ...httpx.Middleware) { a.handle(a.router, http.MethodGet, path, handler, middleware) } func (a *App) POST(path string, handler httpx.Handler, middleware ...httpx.Middleware) { a.handle(a.router, http.MethodPost, path, handler, middleware) } func (a *App) PUT(path string, handler httpx.Handler, middleware ...httpx.Middleware) { a.handle(a.router, http.MethodPut, path, handler, middleware) } func (a *App) PATCH(path string, handler httpx.Handler, middleware ...httpx.Middleware) { a.handle(a.router, http.MethodPatch, path, handler, middleware) } func (a *App) DELETE(path string, handler httpx.Handler, middleware ...httpx.Middleware) { a.handle(a.router, http.MethodDelete, path, handler, middleware) } func (a *App) Any(path string, handler httpx.Handler, middleware ...httpx.Middleware) { a.router.Any(path, a.adapt(handler, middleware...)) } // RouterGroup scopes a route prefix and optional middleware. type RouterGroup struct { group httpx.RouterGroup app *App middlewares []httpx.Middleware } func (a *App) Group(path string, middleware ...httpx.Middleware) *RouterGroup { return &RouterGroup{group: a.router.Group(path), app: a, middlewares: middleware} } func (g *RouterGroup) Use(middleware ...httpx.Middleware) *RouterGroup { g.middlewares = append(g.middlewares, middleware...) return g } func (g *RouterGroup) Group(path string, middleware ...httpx.Middleware) *RouterGroup { combined := append([]httpx.Middleware{}, g.middlewares...) combined = append(combined, middleware...) return &RouterGroup{group: g.group.Group(path), app: g.app, middlewares: combined} } func (g *RouterGroup) route(method, path string, handler httpx.Handler, middleware []httpx.Middleware) { combined := append([]httpx.Middleware{}, g.middlewares...) combined = append(combined, middleware...) g.app.handle(g.group, method, path, handler, combined) } // Handle registers an explicit method within this group's middleware chain. func (g *RouterGroup) Handle(method, path string, handler httpx.Handler, middleware ...httpx.Middleware) { g.route(method, path, handler, middleware) } func (g *RouterGroup) GET(path string, handler httpx.Handler, middleware ...httpx.Middleware) { g.route(http.MethodGet, path, handler, middleware) } func (g *RouterGroup) POST(path string, handler httpx.Handler, middleware ...httpx.Middleware) { g.route(http.MethodPost, path, handler, middleware) } func (g *RouterGroup) PUT(path string, handler httpx.Handler, middleware ...httpx.Middleware) { g.route(http.MethodPut, path, handler, middleware) } func (g *RouterGroup) PATCH(path string, handler httpx.Handler, middleware ...httpx.Middleware) { g.route(http.MethodPatch, path, handler, middleware) } func (g *RouterGroup) DELETE(path string, handler httpx.Handler, middleware ...httpx.Middleware) { g.route(http.MethodDelete, path, handler, middleware) } func (g *RouterGroup) Any(path string, handler httpx.Handler, middleware ...httpx.Middleware) { combined := append([]httpx.Middleware{}, g.middlewares...) combined = append(combined, middleware...) g.group.Any(path, g.app.adapt(handler, combined...)) }