mirror of
https://github.com/labstack/echo.git
synced 2024-12-24 20:14:31 +02:00
Support route naming and generating URLs based on route names (#960)
* Route registration methods return Route object * Renamed Route#Handler to Route#Name * Adding route return value to Any, Match, Static and File methods.
This commit is contained in:
parent
935a60782c
commit
c04b028852
100
echo.go
100
echo.go
@ -86,9 +86,9 @@ type (
|
|||||||
|
|
||||||
// Route contains a handler and information for matching against requests.
|
// Route contains a handler and information for matching against requests.
|
||||||
Route struct {
|
Route struct {
|
||||||
Method string `json:"method"`
|
Method string `json:"method"`
|
||||||
Path string `json:"path"`
|
Path string `json:"path"`
|
||||||
Handler string `json:"handler"`
|
Name string `json:"name"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// HTTPError represents an error that occurred while handling a request.
|
// HTTPError represents an error that occurred while handling a request.
|
||||||
@ -121,7 +121,7 @@ type (
|
|||||||
|
|
||||||
// i is the interface for Echo and Group.
|
// i is the interface for Echo and Group.
|
||||||
i interface {
|
i interface {
|
||||||
GET(string, HandlerFunc, ...MiddlewareFunc)
|
GET(string, HandlerFunc, ...MiddlewareFunc) *Route
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -355,84 +355,88 @@ func (e *Echo) Use(middleware ...MiddlewareFunc) {
|
|||||||
|
|
||||||
// CONNECT registers a new CONNECT route for a path with matching handler in the
|
// CONNECT registers a new CONNECT route for a path with matching handler in the
|
||||||
// router with optional route-level middleware.
|
// router with optional route-level middleware.
|
||||||
func (e *Echo) CONNECT(path string, h HandlerFunc, m ...MiddlewareFunc) {
|
func (e *Echo) CONNECT(path string, h HandlerFunc, m ...MiddlewareFunc) *Route {
|
||||||
e.add(CONNECT, path, h, m...)
|
return e.add(CONNECT, path, h, m...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// DELETE registers a new DELETE route for a path with matching handler in the router
|
// DELETE registers a new DELETE route for a path with matching handler in the router
|
||||||
// with optional route-level middleware.
|
// with optional route-level middleware.
|
||||||
func (e *Echo) DELETE(path string, h HandlerFunc, m ...MiddlewareFunc) {
|
func (e *Echo) DELETE(path string, h HandlerFunc, m ...MiddlewareFunc) *Route {
|
||||||
e.add(DELETE, path, h, m...)
|
return e.add(DELETE, path, h, m...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GET registers a new GET route for a path with matching handler in the router
|
// GET registers a new GET route for a path with matching handler in the router
|
||||||
// with optional route-level middleware.
|
// with optional route-level middleware.
|
||||||
func (e *Echo) GET(path string, h HandlerFunc, m ...MiddlewareFunc) {
|
func (e *Echo) GET(path string, h HandlerFunc, m ...MiddlewareFunc) *Route {
|
||||||
e.add(GET, path, h, m...)
|
return e.add(GET, path, h, m...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// HEAD registers a new HEAD route for a path with matching handler in the
|
// HEAD registers a new HEAD route for a path with matching handler in the
|
||||||
// router with optional route-level middleware.
|
// router with optional route-level middleware.
|
||||||
func (e *Echo) HEAD(path string, h HandlerFunc, m ...MiddlewareFunc) {
|
func (e *Echo) HEAD(path string, h HandlerFunc, m ...MiddlewareFunc) *Route {
|
||||||
e.add(HEAD, path, h, m...)
|
return e.add(HEAD, path, h, m...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// OPTIONS registers a new OPTIONS route for a path with matching handler in the
|
// OPTIONS registers a new OPTIONS route for a path with matching handler in the
|
||||||
// router with optional route-level middleware.
|
// router with optional route-level middleware.
|
||||||
func (e *Echo) OPTIONS(path string, h HandlerFunc, m ...MiddlewareFunc) {
|
func (e *Echo) OPTIONS(path string, h HandlerFunc, m ...MiddlewareFunc) *Route {
|
||||||
e.add(OPTIONS, path, h, m...)
|
return e.add(OPTIONS, path, h, m...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// PATCH registers a new PATCH route for a path with matching handler in the
|
// PATCH registers a new PATCH route for a path with matching handler in the
|
||||||
// router with optional route-level middleware.
|
// router with optional route-level middleware.
|
||||||
func (e *Echo) PATCH(path string, h HandlerFunc, m ...MiddlewareFunc) {
|
func (e *Echo) PATCH(path string, h HandlerFunc, m ...MiddlewareFunc) *Route {
|
||||||
e.add(PATCH, path, h, m...)
|
return e.add(PATCH, path, h, m...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// POST registers a new POST route for a path with matching handler in the
|
// POST registers a new POST route for a path with matching handler in the
|
||||||
// router with optional route-level middleware.
|
// router with optional route-level middleware.
|
||||||
func (e *Echo) POST(path string, h HandlerFunc, m ...MiddlewareFunc) {
|
func (e *Echo) POST(path string, h HandlerFunc, m ...MiddlewareFunc) *Route {
|
||||||
e.add(POST, path, h, m...)
|
return e.add(POST, path, h, m...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// PUT registers a new PUT route for a path with matching handler in the
|
// PUT registers a new PUT route for a path with matching handler in the
|
||||||
// router with optional route-level middleware.
|
// router with optional route-level middleware.
|
||||||
func (e *Echo) PUT(path string, h HandlerFunc, m ...MiddlewareFunc) {
|
func (e *Echo) PUT(path string, h HandlerFunc, m ...MiddlewareFunc) *Route {
|
||||||
e.add(PUT, path, h, m...)
|
return e.add(PUT, path, h, m...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TRACE registers a new TRACE route for a path with matching handler in the
|
// TRACE registers a new TRACE route for a path with matching handler in the
|
||||||
// router with optional route-level middleware.
|
// router with optional route-level middleware.
|
||||||
func (e *Echo) TRACE(path string, h HandlerFunc, m ...MiddlewareFunc) {
|
func (e *Echo) TRACE(path string, h HandlerFunc, m ...MiddlewareFunc) *Route {
|
||||||
e.add(TRACE, path, h, m...)
|
return e.add(TRACE, path, h, m...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Any registers a new route for all HTTP methods and path with matching handler
|
// Any registers a new route for all HTTP methods and path with matching handler
|
||||||
// in the router with optional route-level middleware.
|
// in the router with optional route-level middleware.
|
||||||
func (e *Echo) Any(path string, handler HandlerFunc, middleware ...MiddlewareFunc) {
|
func (e *Echo) Any(path string, handler HandlerFunc, middleware ...MiddlewareFunc) []*Route {
|
||||||
|
routes := make([]*Route, 0)
|
||||||
for _, m := range methods {
|
for _, m := range methods {
|
||||||
e.add(m, path, handler, middleware...)
|
routes = append(routes, e.add(m, path, handler, middleware...))
|
||||||
}
|
}
|
||||||
|
return routes
|
||||||
}
|
}
|
||||||
|
|
||||||
// Match registers a new route for multiple HTTP methods and path with matching
|
// Match registers a new route for multiple HTTP methods and path with matching
|
||||||
// handler in the router with optional route-level middleware.
|
// handler in the router with optional route-level middleware.
|
||||||
func (e *Echo) Match(methods []string, path string, handler HandlerFunc, middleware ...MiddlewareFunc) {
|
func (e *Echo) Match(methods []string, path string, handler HandlerFunc, middleware ...MiddlewareFunc) []*Route {
|
||||||
|
routes := make([]*Route, 0)
|
||||||
for _, m := range methods {
|
for _, m := range methods {
|
||||||
e.add(m, path, handler, middleware...)
|
routes = append(routes, e.add(m, path, handler, middleware...))
|
||||||
}
|
}
|
||||||
|
return routes
|
||||||
}
|
}
|
||||||
|
|
||||||
// Static registers a new route with path prefix to serve static files from the
|
// Static registers a new route with path prefix to serve static files from the
|
||||||
// provided root directory.
|
// provided root directory.
|
||||||
func (e *Echo) Static(prefix, root string) {
|
func (e *Echo) Static(prefix, root string) *Route {
|
||||||
if root == "" {
|
if root == "" {
|
||||||
root = "." // For security we want to restrict to CWD.
|
root = "." // For security we want to restrict to CWD.
|
||||||
}
|
}
|
||||||
static(e, prefix, root)
|
return static(e, prefix, root)
|
||||||
}
|
}
|
||||||
|
|
||||||
func static(i i, prefix, root string) {
|
func static(i i, prefix, root string) *Route {
|
||||||
h := func(c Context) error {
|
h := func(c Context) error {
|
||||||
p, err := PathUnescape(c.Param("*"))
|
p, err := PathUnescape(c.Param("*"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -443,20 +447,20 @@ func static(i i, prefix, root string) {
|
|||||||
}
|
}
|
||||||
i.GET(prefix, h)
|
i.GET(prefix, h)
|
||||||
if prefix == "/" {
|
if prefix == "/" {
|
||||||
i.GET(prefix+"*", h)
|
return i.GET(prefix+"*", h)
|
||||||
} else {
|
|
||||||
i.GET(prefix+"/*", h)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return i.GET(prefix+"/*", h)
|
||||||
}
|
}
|
||||||
|
|
||||||
// File registers a new route with path to serve a static file.
|
// File registers a new route with path to serve a static file.
|
||||||
func (e *Echo) File(path, file string) {
|
func (e *Echo) File(path, file string) *Route {
|
||||||
e.GET(path, func(c Context) error {
|
return e.GET(path, func(c Context) error {
|
||||||
return c.File(file)
|
return c.File(file)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Echo) add(method, path string, handler HandlerFunc, middleware ...MiddlewareFunc) {
|
func (e *Echo) add(method, path string, handler HandlerFunc, middleware ...MiddlewareFunc) *Route {
|
||||||
name := handlerName(handler)
|
name := handlerName(handler)
|
||||||
e.router.Add(method, path, func(c Context) error {
|
e.router.Add(method, path, func(c Context) error {
|
||||||
h := handler
|
h := handler
|
||||||
@ -467,11 +471,12 @@ func (e *Echo) add(method, path string, handler HandlerFunc, middleware ...Middl
|
|||||||
return h(c)
|
return h(c)
|
||||||
})
|
})
|
||||||
r := &Route{
|
r := &Route{
|
||||||
Method: method,
|
Method: method,
|
||||||
Path: path,
|
Path: path,
|
||||||
Handler: name,
|
Name: name,
|
||||||
}
|
}
|
||||||
e.router.routes[method+path] = r
|
e.router.routes[method+path] = r
|
||||||
|
return r
|
||||||
}
|
}
|
||||||
|
|
||||||
// Group creates a new router group with prefix and optional group-level middleware.
|
// Group creates a new router group with prefix and optional group-level middleware.
|
||||||
@ -483,12 +488,22 @@ func (e *Echo) Group(prefix string, m ...MiddlewareFunc) (g *Group) {
|
|||||||
|
|
||||||
// URI generates a URI from handler.
|
// URI generates a URI from handler.
|
||||||
func (e *Echo) URI(handler HandlerFunc, params ...interface{}) string {
|
func (e *Echo) URI(handler HandlerFunc, params ...interface{}) string {
|
||||||
|
name := handlerName(handler)
|
||||||
|
return e.Reverse(name, params...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// URL is an alias for `URI` function.
|
||||||
|
func (e *Echo) URL(h HandlerFunc, params ...interface{}) string {
|
||||||
|
return e.URI(h, params...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reverse generates an URL from route name and provided parameters
|
||||||
|
func (e *Echo) Reverse(name string, params ...interface{}) string {
|
||||||
uri := new(bytes.Buffer)
|
uri := new(bytes.Buffer)
|
||||||
ln := len(params)
|
ln := len(params)
|
||||||
n := 0
|
n := 0
|
||||||
name := handlerName(handler)
|
|
||||||
for _, r := range e.router.routes {
|
for _, r := range e.router.routes {
|
||||||
if r.Handler == name {
|
if r.Name == name {
|
||||||
for i, l := 0, len(r.Path); i < l; i++ {
|
for i, l := 0, len(r.Path); i < l; i++ {
|
||||||
if r.Path[i] == ':' && n < ln {
|
if r.Path[i] == ':' && n < ln {
|
||||||
for ; i < l && r.Path[i] != '/'; i++ {
|
for ; i < l && r.Path[i] != '/'; i++ {
|
||||||
@ -506,11 +521,6 @@ func (e *Echo) URI(handler HandlerFunc, params ...interface{}) string {
|
|||||||
return uri.String()
|
return uri.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
// URL is an alias for `URI` function.
|
|
||||||
func (e *Echo) URL(h HandlerFunc, params ...interface{}) string {
|
|
||||||
return e.URI(h, params...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Routes returns the registered routes.
|
// Routes returns the registered routes.
|
||||||
func (e *Echo) Routes() []*Route {
|
func (e *Echo) Routes() []*Route {
|
||||||
routes := []*Route{}
|
routes := []*Route{}
|
||||||
|
40
group.go
40
group.go
@ -26,48 +26,48 @@ func (g *Group) Use(middleware ...MiddlewareFunc) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// CONNECT implements `Echo#CONNECT()` for sub-routes within the Group.
|
// CONNECT implements `Echo#CONNECT()` for sub-routes within the Group.
|
||||||
func (g *Group) CONNECT(path string, h HandlerFunc, m ...MiddlewareFunc) {
|
func (g *Group) CONNECT(path string, h HandlerFunc, m ...MiddlewareFunc) *Route {
|
||||||
g.add(CONNECT, path, h, m...)
|
return g.add(CONNECT, path, h, m...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// DELETE implements `Echo#DELETE()` for sub-routes within the Group.
|
// DELETE implements `Echo#DELETE()` for sub-routes within the Group.
|
||||||
func (g *Group) DELETE(path string, h HandlerFunc, m ...MiddlewareFunc) {
|
func (g *Group) DELETE(path string, h HandlerFunc, m ...MiddlewareFunc) *Route {
|
||||||
g.add(DELETE, path, h, m...)
|
return g.add(DELETE, path, h, m...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GET implements `Echo#GET()` for sub-routes within the Group.
|
// GET implements `Echo#GET()` for sub-routes within the Group.
|
||||||
func (g *Group) GET(path string, h HandlerFunc, m ...MiddlewareFunc) {
|
func (g *Group) GET(path string, h HandlerFunc, m ...MiddlewareFunc) *Route {
|
||||||
g.add(GET, path, h, m...)
|
return g.add(GET, path, h, m...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// HEAD implements `Echo#HEAD()` for sub-routes within the Group.
|
// HEAD implements `Echo#HEAD()` for sub-routes within the Group.
|
||||||
func (g *Group) HEAD(path string, h HandlerFunc, m ...MiddlewareFunc) {
|
func (g *Group) HEAD(path string, h HandlerFunc, m ...MiddlewareFunc) *Route {
|
||||||
g.add(HEAD, path, h, m...)
|
return g.add(HEAD, path, h, m...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// OPTIONS implements `Echo#OPTIONS()` for sub-routes within the Group.
|
// OPTIONS implements `Echo#OPTIONS()` for sub-routes within the Group.
|
||||||
func (g *Group) OPTIONS(path string, h HandlerFunc, m ...MiddlewareFunc) {
|
func (g *Group) OPTIONS(path string, h HandlerFunc, m ...MiddlewareFunc) *Route {
|
||||||
g.add(OPTIONS, path, h, m...)
|
return g.add(OPTIONS, path, h, m...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// PATCH implements `Echo#PATCH()` for sub-routes within the Group.
|
// PATCH implements `Echo#PATCH()` for sub-routes within the Group.
|
||||||
func (g *Group) PATCH(path string, h HandlerFunc, m ...MiddlewareFunc) {
|
func (g *Group) PATCH(path string, h HandlerFunc, m ...MiddlewareFunc) *Route {
|
||||||
g.add(PATCH, path, h, m...)
|
return g.add(PATCH, path, h, m...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// POST implements `Echo#POST()` for sub-routes within the Group.
|
// POST implements `Echo#POST()` for sub-routes within the Group.
|
||||||
func (g *Group) POST(path string, h HandlerFunc, m ...MiddlewareFunc) {
|
func (g *Group) POST(path string, h HandlerFunc, m ...MiddlewareFunc) *Route {
|
||||||
g.add(POST, path, h, m...)
|
return g.add(POST, path, h, m...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// PUT implements `Echo#PUT()` for sub-routes within the Group.
|
// PUT implements `Echo#PUT()` for sub-routes within the Group.
|
||||||
func (g *Group) PUT(path string, h HandlerFunc, m ...MiddlewareFunc) {
|
func (g *Group) PUT(path string, h HandlerFunc, m ...MiddlewareFunc) *Route {
|
||||||
g.add(PUT, path, h, m...)
|
return g.add(PUT, path, h, m...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TRACE implements `Echo#TRACE()` for sub-routes within the Group.
|
// TRACE implements `Echo#TRACE()` for sub-routes within the Group.
|
||||||
func (g *Group) TRACE(path string, h HandlerFunc, m ...MiddlewareFunc) {
|
func (g *Group) TRACE(path string, h HandlerFunc, m ...MiddlewareFunc) *Route {
|
||||||
g.add(TRACE, path, h, m...)
|
return g.add(TRACE, path, h, m...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Any implements `Echo#Any()` for sub-routes within the Group.
|
// Any implements `Echo#Any()` for sub-routes within the Group.
|
||||||
@ -102,12 +102,12 @@ func (g *Group) File(path, file string) {
|
|||||||
g.echo.File(g.prefix+path, file)
|
g.echo.File(g.prefix+path, file)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *Group) add(method, path string, handler HandlerFunc, middleware ...MiddlewareFunc) {
|
func (g *Group) add(method, path string, handler HandlerFunc, middleware ...MiddlewareFunc) *Route {
|
||||||
// Combine into a new slice to avoid accidentally passing the same slice for
|
// Combine into a new slice to avoid accidentally passing the same slice for
|
||||||
// multiple routes, which would lead to later add() calls overwriting the
|
// multiple routes, which would lead to later add() calls overwriting the
|
||||||
// middleware from earlier calls.
|
// middleware from earlier calls.
|
||||||
m := []MiddlewareFunc{}
|
m := []MiddlewareFunc{}
|
||||||
m = append(m, g.middleware...)
|
m = append(m, g.middleware...)
|
||||||
m = append(m, middleware...)
|
m = append(m, middleware...)
|
||||||
g.echo.add(method, g.prefix+path, handler, m...)
|
return g.echo.add(method, g.prefix+path, handler, m...)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user