mirror of https://github.com/gofiber/fiber.git
✨ v3 (feature): router interface changes (#2176)
* Add(methods []string, path string, handlers ...Handler) Router * - proposed Router interface changes Co-authored-by: rocketlaunchr-cto <rocketlaunchr.cloud@gmail.com>pull/2022/head^2
parent
f26d9b1d4e
commit
709e0952e2
52
app.go
52
app.go
|
@ -644,66 +644,66 @@ func (app *App) Use(args ...any) Router {
|
|||
panic(fmt.Sprintf("use: invalid handler %v\n", reflect.TypeOf(arg)))
|
||||
}
|
||||
}
|
||||
app.register(methodUse, prefix, handlers...)
|
||||
app.register([]string{methodUse}, prefix, nil, handlers...)
|
||||
return app
|
||||
}
|
||||
|
||||
// Get registers a route for GET methods that requests a representation
|
||||
// of the specified resource. Requests using GET should only retrieve data.
|
||||
func (app *App) Get(path string, handlers ...Handler) Router {
|
||||
return app.Add(MethodGet, path, handlers...)
|
||||
func (app *App) Get(path string, handler Handler, middleware ...Handler) Router {
|
||||
return app.Add([]string{MethodGet}, path, handler, middleware...)
|
||||
}
|
||||
|
||||
// Head registers a route for HEAD methods that asks for a response identical
|
||||
// to that of a GET request, but without the response body.
|
||||
func (app *App) Head(path string, handlers ...Handler) Router {
|
||||
return app.Add(MethodHead, path, handlers...)
|
||||
func (app *App) Head(path string, handler Handler, middleware ...Handler) Router {
|
||||
return app.Add([]string{MethodHead}, path, handler, middleware...)
|
||||
}
|
||||
|
||||
// Post registers a route for POST methods that is used to submit an entity to the
|
||||
// specified resource, often causing a change in state or side effects on the server.
|
||||
func (app *App) Post(path string, handlers ...Handler) Router {
|
||||
return app.Add(MethodPost, path, handlers...)
|
||||
func (app *App) Post(path string, handler Handler, middleware ...Handler) Router {
|
||||
return app.Add([]string{MethodPost}, path, handler, middleware...)
|
||||
}
|
||||
|
||||
// Put registers a route for PUT methods that replaces all current representations
|
||||
// of the target resource with the request payload.
|
||||
func (app *App) Put(path string, handlers ...Handler) Router {
|
||||
return app.Add(MethodPut, path, handlers...)
|
||||
func (app *App) Put(path string, handler Handler, middleware ...Handler) Router {
|
||||
return app.Add([]string{MethodPut}, path, handler, middleware...)
|
||||
}
|
||||
|
||||
// Delete registers a route for DELETE methods that deletes the specified resource.
|
||||
func (app *App) Delete(path string, handlers ...Handler) Router {
|
||||
return app.Add(MethodDelete, path, handlers...)
|
||||
func (app *App) Delete(path string, handler Handler, middleware ...Handler) Router {
|
||||
return app.Add([]string{MethodDelete}, path, handler, middleware...)
|
||||
}
|
||||
|
||||
// Connect registers a route for CONNECT methods that establishes a tunnel to the
|
||||
// server identified by the target resource.
|
||||
func (app *App) Connect(path string, handlers ...Handler) Router {
|
||||
return app.Add(MethodConnect, path, handlers...)
|
||||
func (app *App) Connect(path string, handler Handler, middleware ...Handler) Router {
|
||||
return app.Add([]string{MethodConnect}, path, handler, middleware...)
|
||||
}
|
||||
|
||||
// Options registers a route for OPTIONS methods that is used to describe the
|
||||
// communication options for the target resource.
|
||||
func (app *App) Options(path string, handlers ...Handler) Router {
|
||||
return app.Add(MethodOptions, path, handlers...)
|
||||
func (app *App) Options(path string, handler Handler, middleware ...Handler) Router {
|
||||
return app.Add([]string{MethodOptions}, path, handler, middleware...)
|
||||
}
|
||||
|
||||
// Trace registers a route for TRACE methods that performs a message loop-back
|
||||
// test along the path to the target resource.
|
||||
func (app *App) Trace(path string, handlers ...Handler) Router {
|
||||
return app.Add(MethodTrace, path, handlers...)
|
||||
func (app *App) Trace(path string, handler Handler, middleware ...Handler) Router {
|
||||
return app.Add([]string{MethodTrace}, path, handler, middleware...)
|
||||
}
|
||||
|
||||
// Patch registers a route for PATCH methods that is used to apply partial
|
||||
// modifications to a resource.
|
||||
func (app *App) Patch(path string, handlers ...Handler) Router {
|
||||
return app.Add(MethodPatch, path, handlers...)
|
||||
func (app *App) Patch(path string, handler Handler, middleware ...Handler) Router {
|
||||
return app.Add([]string{MethodPatch}, path, handler, middleware...)
|
||||
}
|
||||
|
||||
// Add allows you to specify a HTTP method to register a route
|
||||
func (app *App) Add(method, path string, handlers ...Handler) Router {
|
||||
return app.register(method, path, handlers...)
|
||||
// Add allows you to specify multiple HTTP methods to register a route.
|
||||
func (app *App) Add(methods []string, path string, handler Handler, middleware ...Handler) Router {
|
||||
return app.register(methods, path, handler, middleware...)
|
||||
}
|
||||
|
||||
// Static will create a file server serving static files
|
||||
|
@ -712,10 +712,8 @@ func (app *App) Static(prefix, root string, config ...Static) Router {
|
|||
}
|
||||
|
||||
// All will register the handler on all HTTP methods
|
||||
func (app *App) All(path string, handlers ...Handler) Router {
|
||||
for _, method := range intMethod {
|
||||
_ = app.Add(method, path, handlers...)
|
||||
}
|
||||
func (app *App) All(path string, handler Handler, middleware ...Handler) Router {
|
||||
app.Add(intMethod, path, handler, middleware...)
|
||||
return app
|
||||
}
|
||||
|
||||
|
@ -725,7 +723,7 @@ func (app *App) All(path string, handlers ...Handler) Router {
|
|||
// api.Get("/users", handler)
|
||||
func (app *App) Group(prefix string, handlers ...Handler) Router {
|
||||
if len(handlers) > 0 {
|
||||
app.register(methodUse, prefix, handlers...)
|
||||
app.register([]string{methodUse}, prefix, nil, handlers...)
|
||||
}
|
||||
grp := &Group{Prefix: prefix, app: app}
|
||||
if err := app.hooks.executeOnGroupHooks(*grp); err != nil {
|
||||
|
|
|
@ -438,7 +438,7 @@ func Test_App_Add_Method_Test(t *testing.T) {
|
|||
require.Equal(t, "add: invalid http method JOHN\n", fmt.Sprintf("%v", err))
|
||||
}
|
||||
}()
|
||||
app.Add("JOHN", "/doe", testEmptyHandler)
|
||||
app.Add([]string{"JOHN"}, "/doe", testEmptyHandler)
|
||||
}
|
||||
|
||||
// go test -run Test_App_GETOnly
|
||||
|
|
52
group.go
52
group.go
|
@ -64,67 +64,67 @@ func (grp *Group) Use(args ...any) Router {
|
|||
panic(fmt.Sprintf("use: invalid handler %v\n", reflect.TypeOf(arg)))
|
||||
}
|
||||
}
|
||||
grp.app.register(methodUse, getGroupPath(grp.Prefix, prefix), handlers...)
|
||||
grp.app.register([]string{methodUse}, getGroupPath(grp.Prefix, prefix), nil, handlers...)
|
||||
return grp
|
||||
}
|
||||
|
||||
// Get registers a route for GET methods that requests a representation
|
||||
// of the specified resource. Requests using GET should only retrieve data.
|
||||
func (grp *Group) Get(path string, handlers ...Handler) Router {
|
||||
func (grp *Group) Get(path string, handler Handler, middleware ...Handler) Router {
|
||||
path = getGroupPath(grp.Prefix, path)
|
||||
return grp.app.Add(MethodGet, path, handlers...)
|
||||
return grp.app.Add([]string{MethodGet}, path, handler, middleware...)
|
||||
}
|
||||
|
||||
// Head registers a route for HEAD methods that asks for a response identical
|
||||
// to that of a GET request, but without the response body.
|
||||
func (grp *Group) Head(path string, handlers ...Handler) Router {
|
||||
return grp.Add(MethodHead, path, handlers...)
|
||||
func (grp *Group) Head(path string, handler Handler, middleware ...Handler) Router {
|
||||
return grp.Add([]string{MethodHead}, path, handler, middleware...)
|
||||
}
|
||||
|
||||
// Post registers a route for POST methods that is used to submit an entity to the
|
||||
// specified resource, often causing a change in state or side effects on the server.
|
||||
func (grp *Group) Post(path string, handlers ...Handler) Router {
|
||||
return grp.Add(MethodPost, path, handlers...)
|
||||
func (grp *Group) Post(path string, handler Handler, middleware ...Handler) Router {
|
||||
return grp.Add([]string{MethodPost}, path, handler, middleware...)
|
||||
}
|
||||
|
||||
// Put registers a route for PUT methods that replaces all current representations
|
||||
// of the target resource with the request payload.
|
||||
func (grp *Group) Put(path string, handlers ...Handler) Router {
|
||||
return grp.Add(MethodPut, path, handlers...)
|
||||
func (grp *Group) Put(path string, handler Handler, middleware ...Handler) Router {
|
||||
return grp.Add([]string{MethodPut}, path, handler, middleware...)
|
||||
}
|
||||
|
||||
// Delete registers a route for DELETE methods that deletes the specified resource.
|
||||
func (grp *Group) Delete(path string, handlers ...Handler) Router {
|
||||
return grp.Add(MethodDelete, path, handlers...)
|
||||
func (grp *Group) Delete(path string, handler Handler, middleware ...Handler) Router {
|
||||
return grp.Add([]string{MethodDelete}, path, handler, middleware...)
|
||||
}
|
||||
|
||||
// Connect registers a route for CONNECT methods that establishes a tunnel to the
|
||||
// server identified by the target resource.
|
||||
func (grp *Group) Connect(path string, handlers ...Handler) Router {
|
||||
return grp.Add(MethodConnect, path, handlers...)
|
||||
func (grp *Group) Connect(path string, handler Handler, middleware ...Handler) Router {
|
||||
return grp.Add([]string{MethodConnect}, path, handler, middleware...)
|
||||
}
|
||||
|
||||
// Options registers a route for OPTIONS methods that is used to describe the
|
||||
// communication options for the target resource.
|
||||
func (grp *Group) Options(path string, handlers ...Handler) Router {
|
||||
return grp.Add(MethodOptions, path, handlers...)
|
||||
func (grp *Group) Options(path string, handler Handler, middleware ...Handler) Router {
|
||||
return grp.Add([]string{MethodOptions}, path, handler, middleware...)
|
||||
}
|
||||
|
||||
// Trace registers a route for TRACE methods that performs a message loop-back
|
||||
// test along the path to the target resource.
|
||||
func (grp *Group) Trace(path string, handlers ...Handler) Router {
|
||||
return grp.Add(MethodTrace, path, handlers...)
|
||||
func (grp *Group) Trace(path string, handler Handler, middleware ...Handler) Router {
|
||||
return grp.Add([]string{MethodTrace}, path, handler, middleware...)
|
||||
}
|
||||
|
||||
// Patch registers a route for PATCH methods that is used to apply partial
|
||||
// modifications to a resource.
|
||||
func (grp *Group) Patch(path string, handlers ...Handler) Router {
|
||||
return grp.Add(MethodPatch, path, handlers...)
|
||||
func (grp *Group) Patch(path string, handler Handler, middleware ...Handler) Router {
|
||||
return grp.Add([]string{MethodPatch}, path, handler, middleware...)
|
||||
}
|
||||
|
||||
// Add allows you to specify a HTTP method to register a route
|
||||
func (grp *Group) Add(method, path string, handlers ...Handler) Router {
|
||||
return grp.app.register(method, getGroupPath(grp.Prefix, path), handlers...)
|
||||
// Add allows you to specify multiple HTTP methods to register a route.
|
||||
func (grp *Group) Add(methods []string, path string, handler Handler, middleware ...Handler) Router {
|
||||
return grp.app.register(methods, getGroupPath(grp.Prefix, path), handler, middleware...)
|
||||
}
|
||||
|
||||
// Static will create a file server serving static files
|
||||
|
@ -133,10 +133,8 @@ func (grp *Group) Static(prefix, root string, config ...Static) Router {
|
|||
}
|
||||
|
||||
// All will register the handler on all HTTP methods
|
||||
func (grp *Group) All(path string, handlers ...Handler) Router {
|
||||
for _, method := range intMethod {
|
||||
_ = grp.Add(method, path, handlers...)
|
||||
}
|
||||
func (grp *Group) All(path string, handler Handler, middleware ...Handler) Router {
|
||||
grp.Add(intMethod, path, handler, middleware...)
|
||||
return grp
|
||||
}
|
||||
|
||||
|
@ -147,7 +145,7 @@ func (grp *Group) All(path string, handlers ...Handler) Router {
|
|||
func (grp *Group) Group(prefix string, handlers ...Handler) Router {
|
||||
prefix = getGroupPath(grp.Prefix, prefix)
|
||||
if len(handlers) > 0 {
|
||||
_ = grp.app.register(methodUse, prefix, handlers...)
|
||||
grp.app.register([]string{methodUse}, prefix, nil, handlers...)
|
||||
}
|
||||
return grp.app.Group(prefix)
|
||||
}
|
||||
|
|
68
register.go
68
register.go
|
@ -6,18 +6,18 @@ package fiber
|
|||
|
||||
// Register defines all router handle interface generate by Route().
|
||||
type Register interface {
|
||||
All(handlers ...Handler) Register
|
||||
Get(handlers ...Handler) Register
|
||||
Head(handlers ...Handler) Register
|
||||
Post(handlers ...Handler) Register
|
||||
Put(handlers ...Handler) Register
|
||||
Delete(handlers ...Handler) Register
|
||||
Connect(handlers ...Handler) Register
|
||||
Options(handlers ...Handler) Register
|
||||
Trace(handlers ...Handler) Register
|
||||
Patch(handlers ...Handler) Register
|
||||
All(handler Handler, middleware ...Handler) Register
|
||||
Get(handler Handler, middleware ...Handler) Register
|
||||
Head(handler Handler, middleware ...Handler) Register
|
||||
Post(handler Handler, middleware ...Handler) Register
|
||||
Put(handler Handler, middleware ...Handler) Register
|
||||
Delete(handler Handler, middleware ...Handler) Register
|
||||
Connect(handler Handler, middleware ...Handler) Register
|
||||
Options(handler Handler, middleware ...Handler) Register
|
||||
Trace(handler Handler, middleware ...Handler) Register
|
||||
Patch(handler Handler, middleware ...Handler) Register
|
||||
|
||||
Add(method string, handlers ...Handler) Register
|
||||
Add(methods []string, handler Handler, middleware ...Handler) Register
|
||||
|
||||
Static(root string, config ...Static) Register
|
||||
|
||||
|
@ -47,68 +47,68 @@ type Registering struct {
|
|||
// })
|
||||
//
|
||||
// This method will match all HTTP verbs: GET, POST, PUT, HEAD etc...
|
||||
func (r *Registering) All(handlers ...Handler) Register {
|
||||
r.app.register(methodUse, r.path, handlers...)
|
||||
func (r *Registering) All(handler Handler, middleware ...Handler) Register {
|
||||
r.app.register([]string{methodUse}, r.path, handler, middleware...)
|
||||
return r
|
||||
}
|
||||
|
||||
// Get registers a route for GET methods that requests a representation
|
||||
// of the specified resource. Requests using GET should only retrieve data.
|
||||
func (r *Registering) Get(handlers ...Handler) Register {
|
||||
r.app.Add(MethodHead, r.path, handlers...).Add(MethodGet, r.path, handlers...)
|
||||
func (r *Registering) Get(handler Handler, middleware ...Handler) Register {
|
||||
r.app.Add([]string{MethodHead}, r.path, handler, middleware...).Add([]string{MethodGet}, r.path, handler, middleware...)
|
||||
return r
|
||||
}
|
||||
|
||||
// Head registers a route for HEAD methods that asks for a response identical
|
||||
// to that of a GET request, but without the response body.
|
||||
func (r *Registering) Head(handlers ...Handler) Register {
|
||||
return r.Add(MethodHead, handlers...)
|
||||
func (r *Registering) Head(handler Handler, middleware ...Handler) Register {
|
||||
return r.Add([]string{MethodHead}, handler, middleware...)
|
||||
}
|
||||
|
||||
// Post registers a route for POST methods that is used to submit an entity to the
|
||||
// specified resource, often causing a change in state or side effects on the server.
|
||||
func (r *Registering) Post(handlers ...Handler) Register {
|
||||
return r.Add(MethodPost, handlers...)
|
||||
func (r *Registering) Post(handler Handler, middleware ...Handler) Register {
|
||||
return r.Add([]string{MethodPost}, handler, middleware...)
|
||||
}
|
||||
|
||||
// Put registers a route for PUT methods that replaces all current representations
|
||||
// of the target resource with the request payload.
|
||||
func (r *Registering) Put(handlers ...Handler) Register {
|
||||
return r.Add(MethodPut, handlers...)
|
||||
func (r *Registering) Put(handler Handler, middleware ...Handler) Register {
|
||||
return r.Add([]string{MethodPut}, handler, middleware...)
|
||||
}
|
||||
|
||||
// Delete registers a route for DELETE methods that deletes the specified resource.
|
||||
func (r *Registering) Delete(handlers ...Handler) Register {
|
||||
return r.Add(MethodDelete, handlers...)
|
||||
func (r *Registering) Delete(handler Handler, middleware ...Handler) Register {
|
||||
return r.Add([]string{MethodDelete}, handler, middleware...)
|
||||
}
|
||||
|
||||
// Connect registers a route for CONNECT methods that establishes a tunnel to the
|
||||
// server identified by the target resource.
|
||||
func (r *Registering) Connect(handlers ...Handler) Register {
|
||||
return r.Add(MethodConnect, handlers...)
|
||||
func (r *Registering) Connect(handler Handler, middleware ...Handler) Register {
|
||||
return r.Add([]string{MethodConnect}, handler, middleware...)
|
||||
}
|
||||
|
||||
// Options registers a route for OPTIONS methods that is used to describe the
|
||||
// communication options for the target resource.
|
||||
func (r *Registering) Options(handlers ...Handler) Register {
|
||||
return r.Add(MethodOptions, handlers...)
|
||||
func (r *Registering) Options(handler Handler, middleware ...Handler) Register {
|
||||
return r.Add([]string{MethodOptions}, handler, middleware...)
|
||||
}
|
||||
|
||||
// Trace registers a route for TRACE methods that performs a message loop-back
|
||||
// test along the r.Path to the target resource.
|
||||
func (r *Registering) Trace(handlers ...Handler) Register {
|
||||
return r.Add(MethodTrace, handlers...)
|
||||
func (r *Registering) Trace(handler Handler, middleware ...Handler) Register {
|
||||
return r.Add([]string{MethodTrace}, handler, middleware...)
|
||||
}
|
||||
|
||||
// Patch registers a route for PATCH methods that is used to apply partial
|
||||
// modifications to a resource.
|
||||
func (r *Registering) Patch(handlers ...Handler) Register {
|
||||
return r.Add(MethodPatch, handlers...)
|
||||
func (r *Registering) Patch(handler Handler, middleware ...Handler) Register {
|
||||
return r.Add([]string{MethodPatch}, handler, middleware...)
|
||||
}
|
||||
|
||||
// Add allows you to specify a HTTP method to register a route
|
||||
func (r *Registering) Add(method string, handlers ...Handler) Register {
|
||||
r.app.register(method, r.path, handlers...)
|
||||
// Add allows you to specify multiple HTTP methods to register a route.
|
||||
func (r *Registering) Add(methods []string, handler Handler, middleware ...Handler) Register {
|
||||
r.app.register(methods, r.path, handler, middleware...)
|
||||
return r
|
||||
}
|
||||
|
||||
|
|
163
router.go
163
router.go
|
@ -20,19 +20,19 @@ import (
|
|||
type Router interface {
|
||||
Use(args ...any) Router
|
||||
|
||||
Get(path string, handlers ...Handler) Router
|
||||
Head(path string, handlers ...Handler) Router
|
||||
Post(path string, handlers ...Handler) Router
|
||||
Put(path string, handlers ...Handler) Router
|
||||
Delete(path string, handlers ...Handler) Router
|
||||
Connect(path string, handlers ...Handler) Router
|
||||
Options(path string, handlers ...Handler) Router
|
||||
Trace(path string, handlers ...Handler) Router
|
||||
Patch(path string, handlers ...Handler) Router
|
||||
Get(path string, handler Handler, middleware ...Handler) Router
|
||||
Head(path string, handler Handler, middleware ...Handler) Router
|
||||
Post(path string, handler Handler, middleware ...Handler) Router
|
||||
Put(path string, handler Handler, middleware ...Handler) Router
|
||||
Delete(path string, handler Handler, middleware ...Handler) Router
|
||||
Connect(path string, handler Handler, middleware ...Handler) Router
|
||||
Options(path string, handler Handler, middleware ...Handler) Router
|
||||
Trace(path string, handler Handler, middleware ...Handler) Router
|
||||
Patch(path string, handler Handler, middleware ...Handler) Router
|
||||
|
||||
Add(method, path string, handlers ...Handler) Router
|
||||
Add(methods []string, path string, handler Handler, middleware ...Handler) Router
|
||||
Static(prefix, root string, config ...Static) Router
|
||||
All(path string, handlers ...Handler) Router
|
||||
All(path string, handler Handler, middleware ...Handler) Router
|
||||
|
||||
Group(prefix string, handlers ...Handler) Router
|
||||
|
||||
|
@ -271,77 +271,86 @@ func (app *App) copyRoute(route *Route) *Route {
|
|||
}
|
||||
}
|
||||
|
||||
func (app *App) register(method, pathRaw string, handlers ...Handler) Router {
|
||||
// Uppercase HTTP methods
|
||||
method = utils.ToUpper(method)
|
||||
// Check if the HTTP method is valid unless it's USE
|
||||
if method != methodUse && methodInt(method) == -1 {
|
||||
panic(fmt.Sprintf("add: invalid http method %s\n", method))
|
||||
func (app *App) register(methods []string, pathRaw string, handler Handler, middleware ...Handler) Router {
|
||||
handlers := middleware
|
||||
if handler != nil {
|
||||
handlers = append(handlers, handler)
|
||||
}
|
||||
// A route requires atleast one ctx handler
|
||||
if len(handlers) == 0 {
|
||||
panic(fmt.Sprintf("missing handler in route: %s\n", pathRaw))
|
||||
}
|
||||
// Cannot have an empty path
|
||||
if pathRaw == "" {
|
||||
pathRaw = "/"
|
||||
}
|
||||
// Path always start with a '/'
|
||||
if pathRaw[0] != '/' {
|
||||
pathRaw = "/" + pathRaw
|
||||
}
|
||||
// Create a stripped path in-case sensitive / trailing slashes
|
||||
pathPretty := pathRaw
|
||||
// Case sensitive routing, all to lowercase
|
||||
if !app.config.CaseSensitive {
|
||||
pathPretty = utils.ToLower(pathPretty)
|
||||
}
|
||||
// Strict routing, remove trailing slashes
|
||||
if !app.config.StrictRouting && len(pathPretty) > 1 {
|
||||
pathPretty = strings.TrimRight(pathPretty, "/")
|
||||
}
|
||||
// Is layer a middleware?
|
||||
isUse := method == methodUse
|
||||
// Is path a direct wildcard?
|
||||
isStar := pathPretty == "/*"
|
||||
// Is path a root slash?
|
||||
isRoot := pathPretty == "/"
|
||||
// Parse path parameters
|
||||
parsedRaw := parseRoute(pathRaw)
|
||||
parsedPretty := parseRoute(pathPretty)
|
||||
|
||||
// Create route metadata without pointer
|
||||
route := Route{
|
||||
// Router booleans
|
||||
use: isUse,
|
||||
star: isStar,
|
||||
root: isRoot,
|
||||
for _, method := range methods {
|
||||
|
||||
// Path data
|
||||
path: RemoveEscapeChar(pathPretty),
|
||||
routeParser: parsedPretty,
|
||||
Params: parsedRaw.params,
|
||||
|
||||
// Public data
|
||||
Path: pathRaw,
|
||||
Method: method,
|
||||
Handlers: handlers,
|
||||
}
|
||||
// Increment global handler count
|
||||
atomic.AddUint32(&app.handlersCount, uint32(len(handlers)))
|
||||
|
||||
// Middleware route matches all HTTP methods
|
||||
if isUse {
|
||||
// Add route to all HTTP methods stack
|
||||
for _, m := range intMethod {
|
||||
// Create a route copy to avoid duplicates during compression
|
||||
r := route
|
||||
app.addRoute(m, &r)
|
||||
// Uppercase HTTP methods
|
||||
method = utils.ToUpper(method)
|
||||
// Check if the HTTP method is valid unless it's USE
|
||||
if method != methodUse && methodInt(method) == -1 {
|
||||
panic(fmt.Sprintf("add: invalid http method %s\n", method))
|
||||
}
|
||||
// A route requires atleast one ctx handler
|
||||
if len(handlers) == 0 {
|
||||
panic(fmt.Sprintf("missing handler/middleware in route: %s\n", pathRaw))
|
||||
}
|
||||
// Cannot have an empty path
|
||||
if pathRaw == "" {
|
||||
pathRaw = "/"
|
||||
}
|
||||
// Path always start with a '/'
|
||||
if pathRaw[0] != '/' {
|
||||
pathRaw = "/" + pathRaw
|
||||
}
|
||||
// Create a stripped path in-case sensitive / trailing slashes
|
||||
pathPretty := pathRaw
|
||||
// Case sensitive routing, all to lowercase
|
||||
if !app.config.CaseSensitive {
|
||||
pathPretty = utils.ToLower(pathPretty)
|
||||
}
|
||||
// Strict routing, remove trailing slashes
|
||||
if !app.config.StrictRouting && len(pathPretty) > 1 {
|
||||
pathPretty = strings.TrimRight(pathPretty, "/")
|
||||
}
|
||||
// Is layer a middleware?
|
||||
isUse := method == methodUse
|
||||
// Is path a direct wildcard?
|
||||
isStar := pathPretty == "/*"
|
||||
// Is path a root slash?
|
||||
isRoot := pathPretty == "/"
|
||||
// Parse path parameters
|
||||
parsedRaw := parseRoute(pathRaw)
|
||||
parsedPretty := parseRoute(pathPretty)
|
||||
|
||||
// Create route metadata without pointer
|
||||
route := Route{
|
||||
// Router booleans
|
||||
use: isUse,
|
||||
star: isStar,
|
||||
root: isRoot,
|
||||
|
||||
// Path data
|
||||
path: RemoveEscapeChar(pathPretty),
|
||||
routeParser: parsedPretty,
|
||||
Params: parsedRaw.params,
|
||||
|
||||
// Public data
|
||||
Path: pathRaw,
|
||||
Method: method,
|
||||
Handlers: handlers,
|
||||
}
|
||||
// Increment global handler count
|
||||
atomic.AddUint32(&app.handlersCount, uint32(len(handlers)))
|
||||
|
||||
// Middleware route matches all HTTP methods
|
||||
if isUse {
|
||||
// Add route to all HTTP methods stack
|
||||
for _, m := range intMethod {
|
||||
// Create a route copy to avoid duplicates during compression
|
||||
r := route
|
||||
app.addRoute(m, &r)
|
||||
}
|
||||
} else {
|
||||
// Add route to stack
|
||||
app.addRoute(method, &route)
|
||||
}
|
||||
} else {
|
||||
// Add route to stack
|
||||
app.addRoute(method, &route)
|
||||
}
|
||||
|
||||
return app
|
||||
}
|
||||
|
||||
|
|
|
@ -278,10 +278,10 @@ func Test_Router_Register_Missing_Handler(t *testing.T) {
|
|||
app := New()
|
||||
defer func() {
|
||||
if err := recover(); err != nil {
|
||||
require.Equal(t, "missing handler in route: /doe\n", fmt.Sprintf("%v", err))
|
||||
require.Equal(t, "missing handler/middleware in route: /doe\n", fmt.Sprintf("%v", err))
|
||||
}
|
||||
}()
|
||||
app.register("USE", "/doe")
|
||||
app.register([]string{"USE"}, "/doe", nil)
|
||||
}
|
||||
|
||||
func Test_Ensure_Router_Interface_Implementation(t *testing.T) {
|
||||
|
@ -438,7 +438,7 @@ func registerDummyRoutes(app *App) {
|
|||
return nil
|
||||
}
|
||||
for _, r := range routesFixture.GithubAPI {
|
||||
app.Add(r.Method, r.Path, h)
|
||||
app.Add([]string{r.Method}, r.Path, h)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue