Skip to content

Commit

Permalink
Implement router tree Walker, an analogy to filepath.Walk (#222)
Browse files Browse the repository at this point in the history
* Implement router tree Walker, an analogy to filepath.Walk

func Walk(r Routes, walkFn WalkFunc) error
type WalkFunc func(method string, route string, handler http.Handler, middlewares ...func(http.Handler) http.Handler) error

* Move Walker to tree.go
  • Loading branch information
VojtechVitek authored and Peter Kieltyka committed Jul 25, 2017
1 parent 2f33244 commit 524a020
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 0 deletions.
44 changes: 44 additions & 0 deletions tree.go
Original file line number Diff line number Diff line change
Expand Up @@ -760,3 +760,47 @@ type Route struct {
Handlers map[string]http.Handler
SubRoutes Routes
}

// WalkFunc is the type of the function called for each method and route visited by Walk.
type WalkFunc func(method string, route string, handler http.Handler, middlewares ...func(http.Handler) http.Handler) error

// Walk walks any router tree that implements Routes interface.
func Walk(r Routes, walkFn WalkFunc) error {
return walk(r, walkFn, "")
}

func walk(r Routes, walkFn WalkFunc, parentRoute string, parentMw ...func(http.Handler) http.Handler) error {
for _, route := range r.Routes() {
mws := make([]func(http.Handler) http.Handler, len(parentMw))
copy(mws, parentMw)
mws = append(mws, r.Middlewares()...)

if route.SubRoutes != nil {
if err := walk(route.SubRoutes, walkFn, parentRoute+route.Pattern, mws...); err != nil {
return err
}
continue
}

for method, handler := range route.Handlers {
if method == "*" {
// Ignore a "catchAll" method, since we pass down all the specific methods for each route.
continue
}

fullRoute := parentRoute + route.Pattern

if chain, ok := handler.(*ChainHandler); ok {
if err := walkFn(method, fullRoute, chain.Endpoint, append(mws, chain.Middlewares...)...); err != nil {
return err
}
} else {
if err := walkFn(method, fullRoute, handler, mws...); err != nil {
return err
}
}
}
}

return nil
}
13 changes: 13 additions & 0 deletions tree_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -424,3 +424,16 @@ func BenchmarkTreeGet(b *testing.B) {
tr.FindRoute(mctx, mGET, "/ping/123/456")
}
}

func TestWalker(t *testing.T) {
r := bigMux()

// Walk the muxBig router tree.
if err := Walk(r, func(method string, route string, handler http.Handler, middlewares ...func(http.Handler) http.Handler) error {
t.Logf("%v %v", method, route)

return nil
}); err != nil {
t.Error(err)
}
}

0 comments on commit 524a020

Please sign in to comment.