Skip to content

Commit 252e686

Browse files
author
Sergio Andres Virviescas Santana
committed
Add Router.List to list all registered paths grouped py method
1 parent 206eda7 commit 252e686

File tree

2 files changed

+50
-19
lines changed

2 files changed

+50
-19
lines changed

router.go

Lines changed: 25 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -91,9 +91,10 @@ var (
9191
// Router is a http.Handler which can be used to dispatch requests to different
9292
// handler functions via configurable routes
9393
type Router struct {
94-
parent *Router
95-
beginPath string
96-
trees map[string]*node
94+
parent *Router
95+
beginPath string
96+
trees map[string]*node
97+
registeredPaths map[string][]string
9798

9899
// Enables automatic redirection if the current route can't be matched but a
99100
// handler for the path with (without) the trailing slash exists.
@@ -149,6 +150,8 @@ type Router struct {
149150
func New() *Router {
150151
return &Router{
151152
beginPath: "/",
153+
trees: make(map[string]*node),
154+
registeredPaths: make(map[string][]string),
152155
RedirectTrailingSlash: true,
153156
RedirectFixedPath: true,
154157
HandleMethodNotAllowed: true,
@@ -223,16 +226,14 @@ func (r *Router) Handle(method, path string, handle fasthttp.RequestHandler) {
223226
return
224227
}
225228

226-
if r.trees == nil {
227-
r.trees = make(map[string]*node)
228-
}
229-
230229
root := r.trees[method]
231230
if root == nil {
232231
root = new(node)
233232
r.trees[method] = root
234233
}
235234

235+
r.registeredPaths[method] = append(r.registeredPaths[method], path)
236+
236237
optionalPaths := getOptionalPaths(path)
237238

238239
// if not has optional paths, adds the original
@@ -310,18 +311,6 @@ func (r *Router) ServeFilesCustom(path string, fs *fasthttp.FS) {
310311
})
311312
}
312313

313-
// Lookup allows the manual lookup of a method + path combo.
314-
// This is e.g. useful to build a framework around this router.
315-
// If the path was found, it returns the handle function and the path parameter
316-
// values. Otherwise the third return value indicates whether a redirection to
317-
// the same path with an extra / without the trailing slash should be performed.
318-
func (r *Router) Lookup(method, path string, ctx *fasthttp.RequestCtx) (fasthttp.RequestHandler, bool) {
319-
if root := r.trees[method]; root != nil {
320-
return root.getValue(path, ctx)
321-
}
322-
return nil, false
323-
}
324-
325314
// Handler makes the router implement the fasthttp.ListenAndServe interface.
326315
func (r *Router) Handler(ctx *fasthttp.RequestCtx) {
327316
if r.PanicHandler != nil {
@@ -418,6 +407,23 @@ func (r *Router) Handler(ctx *fasthttp.RequestCtx) {
418407
}
419408
}
420409

410+
// Lookup allows the manual lookup of a method + path combo.
411+
// This is e.g. useful to build a framework around this router.
412+
// If the path was found, it returns the handle function and the path parameter
413+
// values. Otherwise the third return value indicates whether a redirection to
414+
// the same path with an extra / without the trailing slash should be performed.
415+
func (r *Router) Lookup(method, path string, ctx *fasthttp.RequestCtx) (fasthttp.RequestHandler, bool) {
416+
if root := r.trees[method]; root != nil {
417+
return root.getValue(path, ctx)
418+
}
419+
return nil, false
420+
}
421+
422+
// List returns all registered routes grouped by method
423+
func (r *Router) List() map[string][]string {
424+
return r.registeredPaths
425+
}
426+
421427
func (r *Router) allowed(path, reqMethod string) (allow string) {
422428
if path == "*" || path == "/*" { // server-wide
423429
for method := range r.trees {

router_test.go

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import (
1212
"net"
1313
"net/http"
1414
"os"
15+
"reflect"
1516
"strings"
1617
"testing"
1718
"time"
@@ -1029,6 +1030,30 @@ func TestRouterServeFilesCustom(t *testing.T) {
10291030
}
10301031
}
10311032

1033+
func TestRouterList(t *testing.T) {
1034+
expected := map[string][]string{
1035+
"GET": []string{"/bar"},
1036+
"PATCH": []string{"/foo"},
1037+
"POST": []string{"/v1/users/:name/:surname?"},
1038+
"DELETE": []string{"/v1/users/:id?"},
1039+
}
1040+
1041+
r := New()
1042+
r.GET("/bar", func(ctx *fasthttp.RequestCtx) {})
1043+
r.PATCH("/foo", func(ctx *fasthttp.RequestCtx) {})
1044+
1045+
v1 := r.Group("/v1")
1046+
v1.POST("/users/:name/:surname?", func(ctx *fasthttp.RequestCtx) {})
1047+
v1.DELETE("/users/:id?", func(ctx *fasthttp.RequestCtx) {})
1048+
1049+
result := r.List()
1050+
1051+
if !reflect.DeepEqual(result, expected) {
1052+
t.Errorf("Router.List() == %v, want %v", result, expected)
1053+
}
1054+
1055+
}
1056+
10321057
type readWriter struct {
10331058
net.Conn
10341059
r bytes.Buffer

0 commit comments

Comments
 (0)