mirror of https://github.com/gofiber/fiber.git
🐛 bug: fix naming of routes inside groups (#2199)
* 🐛 bug: fix naming of routes inside groups
* fix tests
* bug: fix naming of routes inside groups
Co-authored-by: René Werner <rene@gofiber.io>
pull/2107/head
parent
13247206ab
commit
581af0052d
23
app.go
23
app.go
|
@ -9,6 +9,8 @@ package fiber
|
|||
|
||||
import (
|
||||
"bufio"
|
||||
"encoding/json"
|
||||
"encoding/xml"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net"
|
||||
|
@ -20,9 +22,6 @@ import (
|
|||
"sync"
|
||||
"time"
|
||||
|
||||
"encoding/json"
|
||||
"encoding/xml"
|
||||
|
||||
"github.com/gofiber/fiber/v2/utils"
|
||||
"github.com/valyala/fasthttp"
|
||||
)
|
||||
|
@ -109,7 +108,6 @@ type App struct {
|
|||
hooks *Hooks
|
||||
// Latest route & group
|
||||
latestRoute *Route
|
||||
latestGroup *Group
|
||||
// TLS handler
|
||||
tlsHandler *TLSHandler
|
||||
// Mount fields
|
||||
|
@ -485,7 +483,6 @@ func New(config ...Config) *App {
|
|||
getBytes: utils.UnsafeBytes,
|
||||
getString: utils.UnsafeString,
|
||||
latestRoute: &Route{},
|
||||
latestGroup: &Group{},
|
||||
}
|
||||
|
||||
// Define hooks
|
||||
|
@ -583,8 +580,10 @@ func (app *App) SetTLSHandler(tlsHandler *TLSHandler) {
|
|||
// Name Assign name to specific route.
|
||||
func (app *App) Name(name string) Router {
|
||||
app.mutex.Lock()
|
||||
if strings.HasPrefix(app.latestRoute.path, app.latestGroup.Prefix) {
|
||||
app.latestRoute.Name = app.latestGroup.name + name
|
||||
|
||||
latestGroup := app.latestRoute.group
|
||||
if latestGroup != nil {
|
||||
app.latestRoute.Name = latestGroup.name + name
|
||||
} else {
|
||||
app.latestRoute.Name = name
|
||||
}
|
||||
|
@ -656,7 +655,7 @@ func (app *App) Use(args ...interface{}) Router {
|
|||
panic(fmt.Sprintf("use: invalid handler %v\n", reflect.TypeOf(arg)))
|
||||
}
|
||||
}
|
||||
app.register(methodUse, prefix, handlers...)
|
||||
app.register(methodUse, prefix, nil, handlers...)
|
||||
return app
|
||||
}
|
||||
|
||||
|
@ -715,7 +714,7 @@ func (app *App) Patch(path string, handlers ...Handler) Router {
|
|||
|
||||
// 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...)
|
||||
return app.register(method, path, nil, handlers...)
|
||||
}
|
||||
|
||||
// Static will create a file server serving static files
|
||||
|
@ -736,10 +735,10 @@ func (app *App) All(path string, handlers ...Handler) Router {
|
|||
// api := app.Group("/api")
|
||||
// api.Get("/users", handler)
|
||||
func (app *App) Group(prefix string, handlers ...Handler) Router {
|
||||
if len(handlers) > 0 {
|
||||
app.register(methodUse, prefix, handlers...)
|
||||
}
|
||||
grp := &Group{Prefix: prefix, app: app}
|
||||
if len(handlers) > 0 {
|
||||
app.register(methodUse, prefix, grp, handlers...)
|
||||
}
|
||||
if err := app.hooks.executeOnGroupHooks(*grp); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
|
|
@ -587,15 +587,16 @@ func Test_App_Route_Naming(t *testing.T) {
|
|||
app.Name("doe")
|
||||
|
||||
jane := app.Group("/jane").Name("jane.")
|
||||
group := app.Group("/group")
|
||||
subGroup := jane.Group("/sub-group").Name("sub.")
|
||||
|
||||
jane.Get("/test", handler).Name("test")
|
||||
jane.Trace("/trace", handler).Name("trace")
|
||||
|
||||
group := app.Group("/group")
|
||||
group.Get("/test", handler).Name("test")
|
||||
|
||||
app.Post("/post", handler).Name("post")
|
||||
|
||||
subGroup := jane.Group("/sub-group").Name("sub.")
|
||||
subGroup.Get("/done", handler).Name("done")
|
||||
|
||||
utils.AssertEqual(t, "post", app.GetRoute("post").Name)
|
||||
|
|
35
group.go
35
group.go
|
@ -7,13 +7,13 @@ package fiber
|
|||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Group struct
|
||||
type Group struct {
|
||||
app *App
|
||||
name string
|
||||
app *App
|
||||
parentGroup *Group
|
||||
name string
|
||||
|
||||
Prefix string
|
||||
}
|
||||
|
@ -21,15 +21,14 @@ type Group struct {
|
|||
// Name Assign name to specific route.
|
||||
func (grp *Group) Name(name string) Router {
|
||||
grp.app.mutex.Lock()
|
||||
if strings.HasPrefix(grp.Prefix, grp.app.latestGroup.Prefix) {
|
||||
grp.name = grp.app.latestGroup.name + name
|
||||
|
||||
if grp.parentGroup != nil {
|
||||
grp.name = grp.parentGroup.name + name
|
||||
} else {
|
||||
grp.name = name
|
||||
}
|
||||
|
||||
grp.app.latestGroup = grp
|
||||
|
||||
if err := grp.app.hooks.executeOnGroupNameHooks(*grp.app.latestGroup); err != nil {
|
||||
if err := grp.app.hooks.executeOnGroupNameHooks(*grp); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
grp.app.mutex.Unlock()
|
||||
|
@ -64,15 +63,15 @@ func (grp *Group) Use(args ...interface{}) Router {
|
|||
panic(fmt.Sprintf("use: invalid handler %v\n", reflect.TypeOf(arg)))
|
||||
}
|
||||
}
|
||||
grp.app.register(methodUse, getGroupPath(grp.Prefix, prefix), handlers...)
|
||||
grp.app.register(methodUse, getGroupPath(grp.Prefix, prefix), grp, 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 {
|
||||
path = getGroupPath(grp.Prefix, path)
|
||||
return grp.app.Add(MethodHead, path, handlers...).Add(MethodGet, path, handlers...)
|
||||
grp.Add(MethodHead, path, handlers...)
|
||||
return grp.Add(MethodGet, path, handlers...)
|
||||
}
|
||||
|
||||
// Head registers a route for HEAD methods that asks for a response identical
|
||||
|
@ -124,7 +123,7 @@ func (grp *Group) Patch(path string, handlers ...Handler) Router {
|
|||
|
||||
// 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...)
|
||||
return grp.app.register(method, getGroupPath(grp.Prefix, path), grp, handlers...)
|
||||
}
|
||||
|
||||
// Static will create a file server serving static files
|
||||
|
@ -147,9 +146,17 @@ 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(methodUse, prefix, grp, handlers...)
|
||||
}
|
||||
return grp.app.Group(prefix)
|
||||
|
||||
// Create new group
|
||||
newGrp := &Group{Prefix: prefix, app: grp.app, parentGroup: grp}
|
||||
if err := grp.app.hooks.executeOnGroupHooks(*newGrp); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return newGrp
|
||||
|
||||
}
|
||||
|
||||
// Route is used to define routes with a common prefix inside the common function.
|
||||
|
|
|
@ -52,6 +52,7 @@ type Route struct {
|
|||
root bool // Path equals '/'
|
||||
path string // Prettified path
|
||||
routeParser routeParser // Parameter parser
|
||||
group *Group // Group instance. used for routes in groups
|
||||
|
||||
// Public fields
|
||||
Method string `json:"method"` // HTTP method
|
||||
|
@ -211,7 +212,7 @@ func (app *App) copyRoute(route *Route) *Route {
|
|||
}
|
||||
}
|
||||
|
||||
func (app *App) register(method, pathRaw string, handlers ...Handler) Router {
|
||||
func (app *App) register(method, pathRaw string, group *Group, handlers ...Handler) Router {
|
||||
// Uppercase HTTP methods
|
||||
method = utils.ToUpper(method)
|
||||
// Check if the HTTP method is valid unless it's USE
|
||||
|
@ -262,6 +263,9 @@ func (app *App) register(method, pathRaw string, handlers ...Handler) Router {
|
|||
routeParser: parsedPretty,
|
||||
Params: parsedRaw.params,
|
||||
|
||||
// Group data
|
||||
group: group,
|
||||
|
||||
// Public data
|
||||
Path: pathRaw,
|
||||
Method: method,
|
||||
|
|
|
@ -280,7 +280,7 @@ func Test_Router_Register_Missing_Handler(t *testing.T) {
|
|||
utils.AssertEqual(t, "missing handler in route: /doe\n", fmt.Sprintf("%v", err))
|
||||
}
|
||||
}()
|
||||
app.register("USE", "/doe")
|
||||
app.register("USE", "/doe", nil)
|
||||
}
|
||||
|
||||
func Test_Ensure_Router_Interface_Implementation(t *testing.T) {
|
||||
|
|
Loading…
Reference in New Issue