1
0
mirror of https://github.com/kataras/iris.git synced 2026-01-23 20:05:59 +00:00

Give read access to the current route, a feature that many of you asked for

Former-commit-id: 39295ac1331ee08d3047c84f5c8ea152bce96781
This commit is contained in:
kataras
2017-08-23 16:46:55 +03:00
parent 8b5b6b116a
commit 8b3c44b0a3
8 changed files with 129 additions and 16 deletions

View File

@@ -319,6 +319,20 @@ func (api *APIBuilder) GetRoute(routeName string) *Route {
return api.routes.get(routeName)
}
// GetRouteReadOnly returns the registered "read-only" route based on its name, otherwise nil.
// One note: "routeName" should be case-sensitive. Used by the context to get the current route.
// It returns an interface instead to reduce wrong usage and to keep the decoupled design between
// the context and the routes.
//
// Look `GetRoute` for more.
func (api *APIBuilder) GetRouteReadOnly(routeName string) context.RouteReadOnly {
r := api.GetRoute(routeName)
if r == nil {
return nil
}
return routeReadOnlyWrapper{r}
}
// Use appends Handler(s) to the current Party's routes and child routes.
// If the current Party is the root, then it registers the middleware to all child Parties' routes too.
//

View File

@@ -49,7 +49,15 @@ func (h *routerHandler) getTree(method, subdomain string) *tree {
return nil
}
func (h *routerHandler) addRoute(method, subdomain, path string, handlers context.Handlers) error {
func (h *routerHandler) addRoute(r *Route) error {
var (
routeName = r.Name
method = r.Method
subdomain = r.Subdomain
path = r.Path
handlers = r.Handlers
)
t := h.getTree(method, subdomain)
if t == nil {
@@ -58,7 +66,7 @@ func (h *routerHandler) addRoute(method, subdomain, path string, handlers contex
t = &tree{Method: method, Subdomain: subdomain, Nodes: &n}
h.trees = append(h.trees, t)
}
return t.Nodes.Add(path, handlers)
return t.Nodes.Add(routeName, path, handlers)
}
// NewDefaultHandler returns the handler which is responsible
@@ -125,7 +133,7 @@ func (h *routerHandler) Build(provider RoutesProvider) error {
// on route, it will be stacked shown in this build state
// and no in the lines of the user's action, they should read
// the docs better. Or TODO: add a link here in order to help new users.
if err := h.addRoute(r.Method, r.Subdomain, r.Path, r.Handlers); err != nil {
if err := h.addRoute(r); err != nil {
// node errors:
rp.Add("%v -> %s", err, r.String())
}
@@ -202,8 +210,9 @@ func (h *routerHandler) HandleRequest(ctx context.Context) {
continue
}
}
handlers := t.Nodes.Find(path, ctx.Params())
routeName, handlers := t.Nodes.Find(path, ctx.Params())
if len(handlers) > 0 {
ctx.SetCurrentRouteName(routeName)
ctx.Do(handlers)
// found
return

View File

@@ -13,6 +13,7 @@ type Nodes []*node
type node struct {
s string
routeName string
wildcardParamName string // name of the wildcard parameter, only one per whole Node is allowed
paramNames []string // only-names
childrenNodes Nodes
@@ -28,7 +29,7 @@ var ErrDublicate = errors.New("two or more routes have the same registered path"
/// TODO: clean up needed until v8.5
// Add adds a node to the tree, returns an ErrDublicate error on failure.
func (nodes *Nodes) Add(path string, handlers context.Handlers) error {
func (nodes *Nodes) Add(routeName string, path string, handlers context.Handlers) error {
// println("[Add] adding path: " + path)
// resolve params and if that node should be added as root
var params []string
@@ -66,13 +67,13 @@ func (nodes *Nodes) Add(path string, handlers context.Handlers) error {
for _, idx := range p {
// print("-2 nodes.Add: path: " + path + " params len: ")
// println(len(params))
if err := nodes.add(path[:idx], nil, nil, true); err != nil {
if err := nodes.add(routeName, path[:idx], nil, nil, true); err != nil {
return err
}
// print("-1 nodes.Add: path: " + path + " params len: ")
// println(len(params))
if nidx := idx + 1; len(path) > nidx {
if err := nodes.add(path[:nidx], nil, nil, true); err != nil {
if err := nodes.add(routeName, path[:nidx], nil, nil, true); err != nil {
return err
}
}
@@ -80,7 +81,7 @@ func (nodes *Nodes) Add(path string, handlers context.Handlers) error {
// print("nodes.Add: path: " + path + " params len: ")
// println(len(params))
if err := nodes.add(path, params, handlers, true); err != nil {
if err := nodes.add(routeName, path, params, handlers, true); err != nil {
return err
}
@@ -89,7 +90,7 @@ func (nodes *Nodes) Add(path string, handlers context.Handlers) error {
return nil
}
func (nodes *Nodes) add(path string, paramNames []string, handlers context.Handlers, root bool) (err error) {
func (nodes *Nodes) add(routeName, path string, paramNames []string, handlers context.Handlers, root bool) (err error) {
// println("[add] adding path: " + path)
@@ -115,6 +116,7 @@ func (nodes *Nodes) add(path string, paramNames []string, handlers context.Handl
n := &node{
rootWildcard: rootWildcard,
s: path,
routeName: routeName,
wildcardParamName: wildcardParamName,
paramNames: paramNames,
handlers: handlers,
@@ -154,6 +156,7 @@ loop:
childrenNodes: Nodes{
{
s: n.s[i:],
routeName: n.routeName,
wildcardParamName: n.wildcardParamName, // wildcardParamName
paramNames: n.paramNames,
childrenNodes: n.childrenNodes,
@@ -161,6 +164,7 @@ loop:
},
{
s: path[i:],
routeName: routeName,
wildcardParamName: wildcardParamName,
paramNames: paramNames,
handlers: handlers,
@@ -179,11 +183,13 @@ loop:
*n = node{
s: n.s[:len(path)],
routeName: routeName,
wildcardParamName: wildcardParamName,
paramNames: paramNames,
childrenNodes: Nodes{
{
s: n.s[len(path):],
routeName: n.routeName,
wildcardParamName: n.wildcardParamName, // wildcardParamName
paramNames: n.paramNames,
childrenNodes: n.childrenNodes,
@@ -201,6 +207,7 @@ loop:
if n.wildcardParamName != "" {
n := &node{
s: path,
routeName: routeName,
wildcardParamName: wildcardParamName,
paramNames: paramNames,
handlers: handlers,
@@ -211,7 +218,7 @@ loop:
return
}
// println("4. nodes.Add path: " + path[len(n.s):])
err = n.childrenNodes.add(path[len(n.s):], paramNames, handlers, false)
err = n.childrenNodes.add(routeName, path[len(n.s):], paramNames, handlers, false)
return err
}
@@ -230,6 +237,7 @@ loop:
n := &node{
s: path,
routeName: routeName,
wildcardParamName: wildcardParamName,
paramNames: paramNames,
handlers: handlers,
@@ -243,7 +251,7 @@ loop:
// Find resolves the path, fills its params
// and returns the registered to the resolved node's handlers.
func (nodes Nodes) Find(path string, params *context.RequestParams) context.Handlers {
func (nodes Nodes) Find(path string, params *context.RequestParams) (string, context.Handlers) {
n, paramValues := nodes.findChild(path, nil)
if n != nil {
// map the params,
@@ -270,10 +278,10 @@ func (nodes Nodes) Find(path string, params *context.RequestParams) context.Hand
params.Set(n.wildcardParamName, lastWildcardVal)
}
}
return n.handlers
return n.routeName, n.handlers
}
return nil
return "", nil
}
// Exists returns true if a node with that "path" exists,

View File

@@ -50,7 +50,7 @@ func NewRoute(method, subdomain, unparsedPath string,
}
path = cleanPath(path) // maybe unnecessary here but who cares in this moment
defaultName := method + subdomain + path
defaultName := method + subdomain + tmpl.Src
formattedPath := formatPath(path)
route := &Route{
@@ -106,7 +106,7 @@ func (r *Route) BuildHandlers() {
} // note: no mutex needed, this should be called in-sync when server is not running of course.
}
// String returns the form of METHOD, SUBDOMAIN, TMPL PATH
// String returns the form of METHOD, SUBDOMAIN, TMPL PATH.
func (r Route) String() string {
return fmt.Sprintf("%s %s%s",
r.Method, r.Subdomain, r.Tmpl().Src)
@@ -184,3 +184,19 @@ func (r Route) ResolvePath(args ...string) string {
}
return formattedPath
}
type routeReadOnlyWrapper struct {
*Route
}
func (rd routeReadOnlyWrapper) Name() string {
return rd.Route.Name
}
func (rd routeReadOnlyWrapper) Subdomain() string {
return rd.Route.Subdomain
}
func (rd routeReadOnlyWrapper) Path() string {
return rd.Route.tmpl.Src
}