mirror of
https://github.com/kataras/iris.git
synced 2025-01-23 10:41:03 +01:00
add HandleMany to controller's Before/AfterActivation feature as requested at: https://github.com/kataras/iris/issues/1292
Former-commit-id: c021f49522a214ddc3978a1c8f5e8d32f029eb2d
This commit is contained in:
parent
33dfb42d73
commit
f8d19b3ed2
|
@ -36,6 +36,7 @@ func basicMVC(app *mvc.Application) {
|
|||
|
||||
// GET: http://localhost:8080/basic
|
||||
// GET: http://localhost:8080/basic/custom
|
||||
// GET: http://localhost:8080/basic/custom2
|
||||
app.Handle(new(basicController))
|
||||
|
||||
// All dependencies of the parent *mvc.Application
|
||||
|
@ -73,7 +74,7 @@ type basicController struct {
|
|||
}
|
||||
|
||||
func (c *basicController) BeforeActivation(b mvc.BeforeActivation) {
|
||||
b.Handle("GET", "/custom", "Custom")
|
||||
b.HandleMany("GET", "/custom /custom2", "Custom")
|
||||
}
|
||||
|
||||
func (c *basicController) AfterActivation(a mvc.AfterActivation) {
|
||||
|
|
|
@ -26,7 +26,9 @@ type shared interface {
|
|||
Name() string
|
||||
Router() router.Party
|
||||
GetRoute(methodName string) *router.Route
|
||||
GetRoutes(methodName string) []*router.Route
|
||||
Handle(httpMethod, path, funcName string, middleware ...context.Handler) *router.Route
|
||||
HandleMany(httpMethod, path, funcName string, middleware ...context.Handler) []*router.Route
|
||||
}
|
||||
|
||||
// BeforeActivation is being used as the only one input argument of a
|
||||
|
@ -77,8 +79,8 @@ type ControllerActivator struct {
|
|||
|
||||
// the already-registered routes, key = the controller's function name.
|
||||
// End-devs can change some properties of the *Route on the `BeforeActivator` by using the
|
||||
// `GetRoute(functionName)`. It's a shield against duplications as well.
|
||||
routes map[string]*router.Route
|
||||
// `GetRoute/GetRoutes(functionName)`.
|
||||
routes map[string][]*router.Route
|
||||
|
||||
// the bindings that comes from the Engine and the controller's filled fields if any.
|
||||
// Can be bind-ed to the the new controller's fields and method that is fired
|
||||
|
@ -132,7 +134,7 @@ func newControllerActivator(router router.Party, controller interface{}, depende
|
|||
return c
|
||||
}
|
||||
|
||||
func whatReservedMethods(typ reflect.Type) map[string]*router.Route {
|
||||
func whatReservedMethods(typ reflect.Type) map[string][]*router.Route {
|
||||
methods := []string{"BeforeActivation", "AfterActivation"}
|
||||
// BeforeActivatior/AfterActivation are not routes but they are
|
||||
// reserved names*
|
||||
|
@ -140,9 +142,9 @@ func whatReservedMethods(typ reflect.Type) map[string]*router.Route {
|
|||
methods = append(methods, "BeginRequest", "EndRequest")
|
||||
}
|
||||
|
||||
routes := make(map[string]*router.Route, len(methods))
|
||||
routes := make(map[string][]*router.Route, len(methods))
|
||||
for _, m := range methods {
|
||||
routes[m] = &router.Route{}
|
||||
routes[m] = []*router.Route{}
|
||||
}
|
||||
|
||||
return routes
|
||||
|
@ -199,7 +201,25 @@ func (c *ControllerActivator) Router() router.Party {
|
|||
return c.router
|
||||
}
|
||||
|
||||
// GetRoute returns a registered route based on the controller's method name.
|
||||
// GetRoute returns the first registered route based on the controller's method name.
|
||||
// It can be used to change the route's name, which is useful for reverse routing
|
||||
// inside views. Custom routes can be registered with `Handle`, which returns the *Route.
|
||||
// This method exists mostly for the automatic method parsing based on the known patterns
|
||||
// inside a controller.
|
||||
//
|
||||
// A check for `nil` is necessary for unregistered methods.
|
||||
//
|
||||
// See `GetRoutes` and `Handle` too.
|
||||
func (c *ControllerActivator) GetRoute(methodName string) *router.Route {
|
||||
routes := c.GetRoutes(methodName)
|
||||
if len(routes) > 0 {
|
||||
return routes[0]
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetRoutes returns one or more registered route based on the controller's method name.
|
||||
// It can be used to change the route's name, which is useful for reverse routing
|
||||
// inside views. Custom routes can be registered with `Handle`, which returns the *Route.
|
||||
// This method exists mostly for the automatic method parsing based on the known patterns
|
||||
|
@ -208,10 +228,10 @@ func (c *ControllerActivator) Router() router.Party {
|
|||
// A check for `nil` is necessary for unregistered methods.
|
||||
//
|
||||
// See `Handle` too.
|
||||
func (c *ControllerActivator) GetRoute(methodName string) *router.Route {
|
||||
for name, route := range c.routes {
|
||||
func (c *ControllerActivator) GetRoutes(methodName string) []*router.Route {
|
||||
for name, routes := range c.routes {
|
||||
if name == methodName {
|
||||
return route
|
||||
return routes
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
@ -274,10 +294,33 @@ func (c *ControllerActivator) parseMethod(m reflect.Method) {
|
|||
// and a function name that belongs to the controller, it accepts
|
||||
// a forth, optionally, variadic parameter which is the before handlers.
|
||||
//
|
||||
// Just like `APIBuilder`, it returns the `*router.Route`, if failed
|
||||
// Just like `Party#Handle`, it returns the `*router.Route`, if failed
|
||||
// then it logs the errors and it returns nil, you can check the errors
|
||||
// programmatically by the `APIBuilder#GetReporter`.
|
||||
// programmatically by the `Party#GetReporter`.
|
||||
func (c *ControllerActivator) Handle(method, path, funcName string, middleware ...context.Handler) *router.Route {
|
||||
routes := c.HandleMany(method, path, funcName, middleware...)
|
||||
if len(routes) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
return routes[0]
|
||||
}
|
||||
|
||||
// HandleMany like `Handle` but can register more than one path and HTTP method routes
|
||||
// separated by whitespace on the same controller's method.
|
||||
// Keep note that if the controller's method input arguments are path parameters dependencies
|
||||
// they should match with each of the given paths.
|
||||
//
|
||||
// Just like `Party#HandleMany`:, it returns the `[]*router.Routes`.
|
||||
// Usage:
|
||||
// func (*Controller) BeforeActivation(b mvc.BeforeActivation) {
|
||||
// b.HandleMany("GET", "/path /path1" /path2", "HandlePath")
|
||||
// }
|
||||
func (c *ControllerActivator) HandleMany(method, path, funcName string, middleware ...context.Handler) []*router.Route {
|
||||
return c.handleMany(method, path, funcName, true, middleware...)
|
||||
}
|
||||
|
||||
func (c *ControllerActivator) handleMany(method, path, funcName string, override bool, middleware ...context.Handler) []*router.Route {
|
||||
if method == "" || path == "" || funcName == "" ||
|
||||
c.isReservedMethod(funcName) {
|
||||
// isReservedMethod -> if it's already registered
|
||||
|
@ -313,22 +356,30 @@ func (c *ControllerActivator) Handle(method, path, funcName string, middleware .
|
|||
handler := c.handlerOf(m, funcDependencies)
|
||||
|
||||
// register the handler now.
|
||||
route := c.router.Handle(method, path, append(middleware, handler)...)
|
||||
if route == nil {
|
||||
routes := c.router.HandleMany(method, path, append(middleware, handler)...)
|
||||
if routes == nil {
|
||||
c.addErr(fmt.Errorf("MVC: unable to register a route for the path for '%s.%s'", c.fullName, funcName))
|
||||
return nil
|
||||
}
|
||||
|
||||
// change the main handler's name in order to respect the controller's and give
|
||||
// a proper debug message.
|
||||
route.MainHandlerName = fmt.Sprintf("%s.%s", c.fullName, funcName)
|
||||
for _, r := range routes {
|
||||
// change the main handler's name in order to respect the controller's and give
|
||||
// a proper debug message.
|
||||
r.MainHandlerName = fmt.Sprintf("%s.%s", c.fullName, funcName)
|
||||
}
|
||||
|
||||
// add this as a reserved method name in order to
|
||||
// be sure that the same func will not be registered again,
|
||||
// even if a custom .Handle later on.
|
||||
c.routes[funcName] = route
|
||||
// be sure that the same route
|
||||
// (method is allowed to be registered more than one on different routes - v11.2).
|
||||
|
||||
return route
|
||||
existingRoutes, exist := c.routes[funcName]
|
||||
if override || !exist {
|
||||
c.routes[funcName] = routes
|
||||
} else {
|
||||
c.routes[funcName] = append(existingRoutes, routes...)
|
||||
}
|
||||
|
||||
return routes
|
||||
}
|
||||
|
||||
var emptyIn = []reflect.Value{}
|
||||
|
|
|
@ -4,7 +4,6 @@ import (
|
|||
"github.com/kataras/iris/context"
|
||||
|
||||
"github.com/kataras/neffos"
|
||||
|
||||
"github.com/kataras/neffos/gobwas"
|
||||
"github.com/kataras/neffos/gorilla"
|
||||
"github.com/kataras/neffos/stackexchange/redis"
|
||||
|
|
Loading…
Reference in New Issue
Block a user