From 5be8eac6d88bcae0bd46f661edb9431ae9c7a79e Mon Sep 17 00:00:00 2001 From: Sky Johnson Date: Sat, 26 Apr 2025 17:38:17 -0500 Subject: [PATCH] cleanup --- router.go | 428 ++++++++++++++++++------------------------------- router_test.go | 104 ++++++------ 2 files changed, 204 insertions(+), 328 deletions(-) diff --git a/router.go b/router.go index 89d7a97..386c1b3 100644 --- a/router.go +++ b/router.go @@ -3,58 +3,35 @@ package router import ( "fmt" "net/http" + "slices" ) -// Res is an alias for http.ResponseWriter for shorter, cleaner code type Res = http.ResponseWriter - -// Req is an alias for *http.Request for shorter, cleaner code type Req = *http.Request -// Handler is an interface for handling HTTP requests with path parameters. -type Handler interface { - Serve(params []string) +// Handler is a request handler with parameters. +type Handler func(w Res, r Req, params []string) + +func (h Handler) Serve(w Res, r Req, params []string) { + h(w, r, params) } -// SimpleHandler implements the Handler interface -type SimpleHandler struct { - fn func(params []string) -} - -func (h *SimpleHandler) Serve(params []string) { - h.fn(params) -} - -// NewHandler creates a Handler from a function -func NewHandler(fn func(params []string)) Handler { - return &SimpleHandler{fn: fn} -} - -// Middleware wraps a handler with additional functionality. type Middleware func(Handler) Handler -// node represents a segment in the URL path and its handling logic. type node struct { - segment string // the path segment this node matches - handler Handler // handler for this path, if it's an endpoint - children []*node // child nodes for subsequent path segments - isDynamic bool // true for param segments like [id] - isWildcard bool // true for catch-all segments like *filepath - maxParams uint8 // maximum number of parameters in paths under this node + segment string + handler Handler + children []*node + isDynamic bool + isWildcard bool + maxParams uint8 } -// Router routes HTTP requests by method and path. -// It supports static paths, path parameters, wildcards, and middleware. type Router struct { - get *node - post *node - put *node - patch *node - delete *node - middleware []Middleware // Global middleware + get, post, put, patch, delete *node + middleware []Middleware } -// Group represents a route group with a path prefix and shared middleware. type Group struct { router *Router prefix string @@ -73,90 +50,55 @@ func New() *Router { } } -// ServeHTTP implements http.Handler interface +// ServeHTTP implements http.Handler. func (r *Router) ServeHTTP(w http.ResponseWriter, req *http.Request) { - handler, params, found := r.Lookup(req.Method, req.URL.Path) - if !found { + h, params, ok := r.Lookup(req.Method, req.URL.Path) + if !ok { http.NotFound(w, req) return } - - // Create an HTTP-specific handler wrapper - httpHandler := &httpHandler{ - w: w, - r: req, - h: func(w http.ResponseWriter, r *http.Request, params []string) { - handler.Serve(params) - }, - } - - httpHandler.Serve(params) + h(w, req, params) } -// httpHandler adapts net/http handlers to the router. -type httpHandler struct { - w Res - r Req - h func(w Res, r Req, params []string) -} - -// Serve executes the http handler with parameters. -func (h *httpHandler) Serve(params []string) { - h.h(h.w, h.r, params) -} - -// Use adds middleware to the router's global middleware stack. -func (r *Router) Use(middleware ...Middleware) *Router { - r.middleware = append(r.middleware, middleware...) +// Use adds middleware to the router. +func (r *Router) Use(mw ...Middleware) *Router { + r.middleware = append(r.middleware, mw...) return r } -// Group creates a new route group with the given path prefix. +// Group creates a new route group. func (r *Router) Group(prefix string) *Group { - return &Group{ - router: r, - prefix: prefix, - middleware: []Middleware{}, - } + return &Group{router: r, prefix: prefix, middleware: []Middleware{}} } -// Use adds middleware to the group's middleware stack. -func (g *Group) Use(middleware ...Middleware) *Group { - g.middleware = append(g.middleware, middleware...) +// Use adds middleware to the group. +func (g *Group) Use(mw ...Middleware) *Group { + g.middleware = append(g.middleware, mw...) return g } -// Group creates a nested group with an additional prefix. +// Group creates a nested group. func (g *Group) Group(prefix string) *Group { - return &Group{ - router: g.router, - prefix: g.prefix + prefix, - middleware: append([]Middleware{}, g.middleware...), - } + return &Group{router: g.router, prefix: g.prefix + prefix, middleware: slices.Clone(g.middleware)} } -// applyMiddleware wraps a handler with middleware in reverse order. -func applyMiddleware(handler Handler, middleware []Middleware) Handler { - h := handler - for i := len(middleware) - 1; i >= 0; i-- { - h = middleware[i](h) +// applyMiddleware applies middleware in reverse order. +func applyMiddleware(h Handler, mw []Middleware) Handler { + for i := len(mw) - 1; i >= 0; i-- { + h = mw[i](h) } return h } -// HandlerFunc is a function that handles HTTP requests with parameters. -type HandlerFunc func(w http.ResponseWriter, r *http.Request, params []string) - // Handle registers a handler for the given method and path. -func (r *Router) Handle(method, path string, handler HandlerFunc) error { +func (r *Router) Handle(method, path string, h Handler) error { root := r.methodNode(method) if root == nil { return fmt.Errorf("unsupported method: %s", method) } - return r.addRoute(root, path, &httpHandler{h: handler}, r.middleware) + return r.addRoute(root, path, h, r.middleware) } -// methodNode returns the root node for the given HTTP method. func (r *Router) methodNode(method string) *node { switch method { case "GET": @@ -174,292 +116,244 @@ func (r *Router) methodNode(method string) *node { } } -// Get registers a handler for GET requests at the given path. -func (r *Router) Get(path string, handler HandlerFunc) error { - return r.Handle("GET", path, handler) +// Get registers a GET handler. +func (r *Router) Get(path string, h Handler) error { + return r.Handle("GET", path, h) } -// Post registers a handler for POST requests at the given path. -func (r *Router) Post(path string, handler HandlerFunc) error { - return r.Handle("POST", path, handler) +// Post registers a POST handler. +func (r *Router) Post(path string, h Handler) error { + return r.Handle("POST", path, h) } -// Put registers a handler for PUT requests at the given path. -func (r *Router) Put(path string, handler HandlerFunc) error { - return r.Handle("PUT", path, handler) +// Put registers a PUT handler. +func (r *Router) Put(path string, h Handler) error { + return r.Handle("PUT", path, h) } -// Patch registers a handler for PATCH requests at the given path. -func (r *Router) Patch(path string, handler HandlerFunc) error { - return r.Handle("PATCH", path, handler) +// Patch registers a PATCH handler. +func (r *Router) Patch(path string, h Handler) error { + return r.Handle("PATCH", path, h) } -// Delete registers a handler for DELETE requests at the given path. -func (r *Router) Delete(path string, handler HandlerFunc) error { - return r.Handle("DELETE", path, handler) +// Delete registers a DELETE handler. +func (r *Router) Delete(path string, h Handler) error { + return r.Handle("DELETE", path, h) } -// buildGroupMiddleware returns combined middleware for the group func (g *Group) buildGroupMiddleware() []Middleware { - middleware := append([]Middleware{}, g.router.middleware...) - return append(middleware, g.middleware...) + mw := slices.Clone(g.router.middleware) + return append(mw, g.middleware...) } -// Handle registers a handler for the given method and path. -func (g *Group) Handle(method, path string, handler HandlerFunc) error { +// Handle registers a handler in the group. +func (g *Group) Handle(method, path string, h Handler) error { root := g.router.methodNode(method) if root == nil { return fmt.Errorf("unsupported method: %s", method) } - - fullPath := g.prefix + path - return g.router.addRoute(root, fullPath, &httpHandler{h: handler}, g.buildGroupMiddleware()) + return g.router.addRoute(root, g.prefix+path, h, g.buildGroupMiddleware()) } -// Get registers a handler for GET requests at the given path. -func (g *Group) Get(path string, handler HandlerFunc) error { - return g.Handle("GET", path, handler) +// Get registers a GET handler in the group. +func (g *Group) Get(path string, h Handler) error { + return g.Handle("GET", path, h) } -// Post registers a handler for POST requests at the given path. -func (g *Group) Post(path string, handler HandlerFunc) error { - return g.Handle("POST", path, handler) +// Post registers a POST handler in the group. +func (g *Group) Post(path string, h Handler) error { + return g.Handle("POST", path, h) } -// Put registers a handler for PUT requests at the given path. -func (g *Group) Put(path string, handler HandlerFunc) error { - return g.Handle("PUT", path, handler) +// Put registers a PUT handler in the group. +func (g *Group) Put(path string, h Handler) error { + return g.Handle("PUT", path, h) } -// Patch registers a handler for PATCH requests at the given path. -func (g *Group) Patch(path string, handler HandlerFunc) error { - return g.Handle("PATCH", path, handler) +// Patch registers a PATCH handler in the group. +func (g *Group) Patch(path string, h Handler) error { + return g.Handle("PATCH", path, h) } -// Delete registers a handler for DELETE requests at the given path. -func (g *Group) Delete(path string, handler HandlerFunc) error { - return g.Handle("DELETE", path, handler) +// Delete registers a DELETE handler in the group. +func (g *Group) Delete(path string, h Handler) error { + return g.Handle("DELETE", path, h) } -// WithMiddleware applies specific middleware to the next route registration. -func (r *Router) WithMiddleware(middleware ...Middleware) *MiddlewareRouter { - return &MiddlewareRouter{ - router: r, - middleware: middleware, - } +// WithMiddleware applies specific middleware for next registration. +func (r *Router) WithMiddleware(mw ...Middleware) *MiddlewareRouter { + return &MiddlewareRouter{router: r, middleware: mw} } -// WithMiddleware applies specific middleware to the next route registration. -func (g *Group) WithMiddleware(middleware ...Middleware) *MiddlewareGroup { - return &MiddlewareGroup{ - group: g, - middleware: middleware, - } +// WithMiddleware applies specific middleware for next group route. +func (g *Group) WithMiddleware(mw ...Middleware) *MiddlewareGroup { + return &MiddlewareGroup{group: g, middleware: mw} } -// MiddlewareRouter handles route registration with specific middleware. type MiddlewareRouter struct { router *Router middleware []Middleware } -// MiddlewareGroup handles group route registration with specific middleware. type MiddlewareGroup struct { group *Group middleware []Middleware } -// buildMiddleware returns combined middleware for the middleware router func (mr *MiddlewareRouter) buildMiddleware() []Middleware { - middleware := append([]Middleware{}, mr.router.middleware...) - return append(middleware, mr.middleware...) + mw := slices.Clone(mr.router.middleware) + return append(mw, mr.middleware...) } -// Handle registers a handler for the given method and path. -func (mr *MiddlewareRouter) Handle(method, path string, handler HandlerFunc) error { +// Handle registers a handler with middleware router. +func (mr *MiddlewareRouter) Handle(method, path string, h Handler) error { root := mr.router.methodNode(method) if root == nil { return fmt.Errorf("unsupported method: %s", method) } - - return mr.router.addRoute(root, path, &httpHandler{h: handler}, mr.buildMiddleware()) + return mr.router.addRoute(root, path, h, mr.buildMiddleware()) } -// Get registers a handler for GET requests with specific middleware. -func (mr *MiddlewareRouter) Get(path string, handler HandlerFunc) error { - return mr.Handle("GET", path, handler) +// Get registers a GET handler with middleware router. +func (mr *MiddlewareRouter) Get(path string, h Handler) error { + return mr.Handle("GET", path, h) } -// Post registers a handler for POST requests with specific middleware. -func (mr *MiddlewareRouter) Post(path string, handler HandlerFunc) error { - return mr.Handle("POST", path, handler) +// Post registers a POST handler with middleware router. +func (mr *MiddlewareRouter) Post(path string, h Handler) error { + return mr.Handle("POST", path, h) } -// Put registers a handler for PUT requests with specific middleware. -func (mr *MiddlewareRouter) Put(path string, handler HandlerFunc) error { - return mr.Handle("PUT", path, handler) +// Put registers a PUT handler with middleware router. +func (mr *MiddlewareRouter) Put(path string, h Handler) error { + return mr.Handle("PUT", path, h) } -// Patch registers a handler for PATCH requests with specific middleware. -func (mr *MiddlewareRouter) Patch(path string, handler HandlerFunc) error { - return mr.Handle("PATCH", path, handler) +// Patch registers a PATCH handler with middleware router. +func (mr *MiddlewareRouter) Patch(path string, h Handler) error { + return mr.Handle("PATCH", path, h) } -// Delete registers a handler for DELETE requests with specific middleware. -func (mr *MiddlewareRouter) Delete(path string, handler HandlerFunc) error { - return mr.Handle("DELETE", path, handler) +// Delete registers a DELETE handler with middleware router. +func (mr *MiddlewareRouter) Delete(path string, h Handler) error { + return mr.Handle("DELETE", path, h) } -// buildMiddleware returns combined middleware for the middleware group func (mg *MiddlewareGroup) buildMiddleware() []Middleware { - middleware := append([]Middleware{}, mg.group.router.middleware...) - middleware = append(middleware, mg.group.middleware...) - return append(middleware, mg.middleware...) + mw := slices.Clone(mg.group.router.middleware) + mw = append(mw, mg.group.middleware...) + return append(mw, mg.middleware...) } -// Handle registers a handler for the given method and path. -func (mg *MiddlewareGroup) Handle(method, path string, handler HandlerFunc) error { +// Handle registers a handler with middleware group. +func (mg *MiddlewareGroup) Handle(method, path string, h Handler) error { root := mg.group.router.methodNode(method) if root == nil { return fmt.Errorf("unsupported method: %s", method) } - - fullPath := mg.group.prefix + path - return mg.group.router.addRoute(root, fullPath, &httpHandler{h: handler}, mg.buildMiddleware()) + return mg.group.router.addRoute(root, mg.group.prefix+path, h, mg.buildMiddleware()) } -// Get registers a handler for GET requests with specific middleware. -func (mg *MiddlewareGroup) Get(path string, handler HandlerFunc) error { - return mg.Handle("GET", path, handler) +// Get registers a GET handler with middleware group. +func (mg *MiddlewareGroup) Get(path string, h Handler) error { + return mg.Handle("GET", path, h) } -// Post registers a handler for POST requests with specific middleware. -func (mg *MiddlewareGroup) Post(path string, handler HandlerFunc) error { - return mg.Handle("POST", path, handler) +// Post registers a POST handler with middleware group. +func (mg *MiddlewareGroup) Post(path string, h Handler) error { + return mg.Handle("POST", path, h) } -// Put registers a handler for PUT requests with specific middleware. -func (mg *MiddlewareGroup) Put(path string, handler HandlerFunc) error { - return mg.Handle("PUT", path, handler) +// Put registers a PUT handler with middleware group. +func (mg *MiddlewareGroup) Put(path string, h Handler) error { + return mg.Handle("PUT", path, h) } -// Patch registers a handler for PATCH requests with specific middleware. -func (mg *MiddlewareGroup) Patch(path string, handler HandlerFunc) error { - return mg.Handle("PATCH", path, handler) +// Patch registers a PATCH handler with middleware group. +func (mg *MiddlewareGroup) Patch(path string, h Handler) error { + return mg.Handle("PATCH", path, h) } -// Delete registers a handler for DELETE requests with specific middleware. -func (mg *MiddlewareGroup) Delete(path string, handler HandlerFunc) error { - return mg.Handle("DELETE", path, handler) +// Delete registers a DELETE handler with middleware group. +func (mg *MiddlewareGroup) Delete(path string, h Handler) error { + return mg.Handle("DELETE", path, h) } -// Adapter for standard http.HandlerFunc -func StandardHandler(handler http.HandlerFunc) HandlerFunc { - return func(w http.ResponseWriter, r *http.Request, _ []string) { - handler(w, r) - } -} - -// readSegment extracts the next path segment starting at the given position. -// Returns the segment, the position after it, and whether there are more segments. +// readSegment extracts the next path segment. func readSegment(path string, start int) (segment string, end int, hasMore bool) { if start >= len(path) { return "", start, false } - if path[start] == '/' { start++ } - if start >= len(path) { return "", start, false } - end = start for end < len(path) && path[end] != '/' { end++ } - return path[start:end], end, end < len(path) } -// addRoute adds a new route to the prefix tree with middleware. -func (r *Router) addRoute(root *node, path string, handler Handler, middleware []Middleware) error { - wrappedHandler := applyMiddleware(handler, middleware) - +// addRoute adds a new route to the trie. +func (r *Router) addRoute(root *node, path string, h Handler, mw []Middleware) error { + h = applyMiddleware(h, mw) if path == "/" { - root.handler = wrappedHandler + root.handler = h return nil } - current := root pos := 0 - var lastWildcard bool - paramsCount := uint8(0) - + lastWC := false + count := uint8(0) for { - segment, newPos, hasMore := readSegment(path, pos) - if segment == "" { + seg, newPos, more := readSegment(path, pos) + if seg == "" { break } - - isDynamic := len(segment) > 2 && segment[0] == '[' && segment[len(segment)-1] == ']' - isWildcard := len(segment) > 0 && segment[0] == '*' - - if isWildcard { - if lastWildcard { + isDyn := len(seg) > 2 && seg[0] == '[' && seg[len(seg)-1] == ']' + isWC := len(seg) > 0 && seg[0] == '*' + if isWC { + if lastWC || more { return fmt.Errorf("wildcard must be the last segment in the path") } - if hasMore { - return fmt.Errorf("wildcard must be the last segment in the path") - } - lastWildcard = true + lastWC = true } - - if isDynamic || isWildcard { - paramsCount++ + if isDyn || isWC { + count++ } - var child *node - for _, n := range current.children { - if n.segment == segment { - child = n + for _, c := range current.children { + if c.segment == seg { + child = c break } } - if child == nil { - child = &node{ - segment: segment, - isDynamic: isDynamic, - isWildcard: isWildcard, - } + child = &node{segment: seg, isDynamic: isDyn, isWildcard: isWC} current.children = append(current.children, child) } - - if child.maxParams < paramsCount { - child.maxParams = paramsCount + if child.maxParams < count { + child.maxParams = count } current = child pos = newPos } - - current.handler = wrappedHandler + current.handler = h return nil } -// Lookup finds a handler matching the given method and path. -// Returns the handler, any captured parameters, and whether a match was found. +// Lookup finds a handler matching method and path. func (r *Router) Lookup(method, path string) (Handler, []string, bool) { root := r.methodNode(method) if root == nil { return nil, nil, false } - if path == "/" { return root.handler, []string{}, root.handler != nil } - params := make([]string, 0, root.maxParams) h, found := match(root, path, 0, ¶ms) if !found { @@ -468,41 +362,35 @@ func (r *Router) Lookup(method, path string) (Handler, []string, bool) { return h, params, true } -// match recursively traverses the prefix tree to find a matching handler. -// It populates params with any captured path parameters or wildcard matches. +// match traverses the trie to find a handler. func match(current *node, path string, start int, params *[]string) (Handler, bool) { - // Check for wildcard children first - for _, child := range current.children { - if child.isWildcard { - remaining := path[start:] - if len(remaining) > 0 && remaining[0] == '/' { - remaining = remaining[1:] + for _, c := range current.children { + if c.isWildcard { + rem := path[start:] + if len(rem) > 0 && rem[0] == '/' { + rem = rem[1:] } - *params = append(*params, remaining) - return child.handler, child.handler != nil + *params = append(*params, rem) + return c.handler, c.handler != nil } } - - // Read current segment - segment, pos, hasMore := readSegment(path, start) - if segment == "" { + seg, pos, more := readSegment(path, start) + if seg == "" { return current.handler, current.handler != nil } - - // Try to match children - for _, child := range current.children { - if child.segment == segment || child.isDynamic { - if child.isDynamic { - *params = append(*params, segment) + for _, c := range current.children { + if c.segment == seg || c.isDynamic { + if c.isDynamic { + *params = append(*params, seg) } - if !hasMore { - return child.handler, child.handler != nil + if !more { + return c.handler, c.handler != nil } - if h, found := match(child, path, pos, params); found { + h, ok := match(c, path, pos, params) + if ok { return h, true } } } - return nil, false } diff --git a/router_test.go b/router_test.go index ee5e37d..95c5fd6 100644 --- a/router_test.go +++ b/router_test.go @@ -10,24 +10,18 @@ import ( func TestRootPath(t *testing.T) { r := New() - r.Get("/", func(w Res, r Req, params []string) { - // No-op for testing - }) + r.Get("/", func(w Res, r Req, params []string) {}) - h, params, found := r.Lookup("GET", "/") + _, _, found := r.Lookup("GET", "/") assert.True(t, found) - h.Serve(params) } func TestStaticPath(t *testing.T) { r := New() - r.Get("/users/all", func(w Res, r Req, params []string) { - // No-op for testing - }) + r.Get("/users/all", func(w Res, r Req, params []string) {}) - h, params, found := r.Lookup("GET", "/users/all") + _, _, found := r.Lookup("GET", "/users/all") assert.True(t, found) - h.Serve(params) } func TestSingleParameter(t *testing.T) { @@ -41,7 +35,7 @@ func TestSingleParameter(t *testing.T) { h, params, found := r.Lookup("GET", "/users/123") assert.True(t, found) - h.Serve(params) + h.Serve(nil, nil, params) assert.True(t, called) } @@ -57,15 +51,13 @@ func TestMultipleParameters(t *testing.T) { h, params, found := r.Lookup("GET", "/users/123/posts/456") assert.True(t, found) - h.Serve(params) + h.Serve(nil, nil, params) assert.True(t, called) } func TestNonExistentPath(t *testing.T) { r := New() - r.Get("/users/[id]", func(w Res, r Req, params []string) { - // No-op for testing - }) + r.Get("/users/[id]", func(w Res, r Req, params []string) {}) _, _, found := r.Lookup("GET", "/posts/123") assert.False(t, found) @@ -73,9 +65,7 @@ func TestNonExistentPath(t *testing.T) { func TestWrongMethod(t *testing.T) { r := New() - r.Get("/users/[id]", func(w Res, r Req, params []string) { - // No-op for testing - }) + r.Get("/users/[id]", func(w Res, r Req, params []string) {}) _, _, found := r.Lookup("POST", "/users/123") assert.False(t, found) @@ -92,7 +82,7 @@ func TestTrailingSlash(t *testing.T) { h, params, found := r.Lookup("GET", "/users/123/") assert.True(t, found) - h.Serve(params) + h.Serve(nil, nil, params) assert.True(t, called) } @@ -129,7 +119,7 @@ func TestWildcardPath(t *testing.T) { h, params, found := r.Lookup("GET", "/files/docs/report.pdf") assert.True(t, found) - h.Serve(params) + h.Serve(nil, nil, params) assert.True(t, called) }) @@ -143,7 +133,7 @@ func TestWildcardPath(t *testing.T) { h, params, found := r.Lookup("GET", "/download/") assert.True(t, found) - h.Serve(params) + h.Serve(nil, nil, params) assert.True(t, called) }) @@ -158,7 +148,7 @@ func TestWildcardPath(t *testing.T) { h, params, found := r.Lookup("GET", "/users/123/settings/profile/avatar") assert.True(t, found) - h.Serve(params) + h.Serve(nil, nil, params) assert.True(t, called) }) @@ -178,13 +168,11 @@ func TestMiddleware(t *testing.T) { t.Run("global middleware", func(t *testing.T) { r := New() - // Track middleware execution executed := false - r.Use(func(next Handler) Handler { - return NewHandler(func(params []string) { + return Handler(func(w Res, r Req, params []string) { executed = true - next.Serve(params) + next(w, r, params) }) }) @@ -192,7 +180,7 @@ func TestMiddleware(t *testing.T) { h, params, found := r.Lookup("GET", "/test") assert.True(t, found) - h.Serve(params) + h.Serve(nil, nil, params) assert.True(t, executed) }) @@ -203,17 +191,17 @@ func TestMiddleware(t *testing.T) { order := []int{} r.Use(func(next Handler) Handler { - return NewHandler(func(params []string) { + return Handler(func(w Res, r Req, params []string) { order = append(order, 1) - next.Serve(params) + next.Serve(nil, nil, params) order = append(order, 4) }) }) r.Use(func(next Handler) Handler { - return NewHandler(func(params []string) { + return Handler(func(w Res, r Req, params []string) { order = append(order, 2) - next.Serve(params) + next.Serve(nil, nil, params) order = append(order, 3) }) }) @@ -224,7 +212,7 @@ func TestMiddleware(t *testing.T) { h, params, found := r.Lookup("GET", "/test") assert.True(t, found) - h.Serve(params) + h.Serve(nil, nil, params) // Check middleware execution order (first middleware wraps second) assert.Equal(t, len(order), 5) @@ -241,9 +229,9 @@ func TestMiddleware(t *testing.T) { executed := false middleware := func(next Handler) Handler { - return NewHandler(func(params []string) { + return Handler(func(w Res, r Req, params []string) { executed = true - next.Serve(params) + next.Serve(nil, nil, params) }) } @@ -251,7 +239,7 @@ func TestMiddleware(t *testing.T) { h, params, found := r.Lookup("GET", "/test") assert.True(t, found) - h.Serve(params) + h.Serve(nil, nil, params) assert.True(t, executed) }) } @@ -267,7 +255,7 @@ func TestGroup(t *testing.T) { h, params, found := r.Lookup("GET", "/api/users") assert.True(t, found) - h.Serve(params) + h.Serve(nil, nil, params) }) t.Run("nested groups", func(t *testing.T) { @@ -280,7 +268,7 @@ func TestGroup(t *testing.T) { h, params, found := r.Lookup("GET", "/api/v1/users") assert.True(t, found) - h.Serve(params) + h.Serve(nil, nil, params) }) t.Run("group middleware", func(t *testing.T) { @@ -290,9 +278,9 @@ func TestGroup(t *testing.T) { // Create group with middleware api := r.Group("/api") api.Use(func(next Handler) Handler { - return NewHandler(func(params []string) { + return Handler(func(w Res, r Req, params []string) { executed = true - next.Serve(params) + next.Serve(nil, nil, params) }) }) @@ -300,7 +288,7 @@ func TestGroup(t *testing.T) { h, params, found := r.Lookup("GET", "/api/users") assert.True(t, found) - h.Serve(params) + h.Serve(nil, nil, params) assert.True(t, executed) }) @@ -311,18 +299,18 @@ func TestGroup(t *testing.T) { // Create group with middleware api := r.Group("/api") api.Use(func(next Handler) Handler { - return NewHandler(func(params []string) { + return Handler(func(w Res, r Req, params []string) { order = append(order, 1) - next.Serve(params) + next.Serve(nil, nil, params) }) }) // Create nested group with additional middleware v1 := api.Group("/v1") v1.Use(func(next Handler) Handler { - return NewHandler(func(params []string) { + return Handler(func(w Res, r Req, params []string) { order = append(order, 2) - next.Serve(params) + next.Serve(nil, nil, params) }) }) @@ -332,7 +320,7 @@ func TestGroup(t *testing.T) { h, params, found := r.Lookup("GET", "/api/v1/users") assert.True(t, found) - h.Serve(params) + h.Serve(nil, nil, params) // Check middleware execution order assert.Equal(t, len(order), 3) @@ -348,17 +336,17 @@ func TestGroup(t *testing.T) { // Create group with middleware api := r.Group("/api") api.Use(func(next Handler) Handler { - return NewHandler(func(params []string) { + return Handler(func(w Res, r Req, params []string) { order = append(order, 1) - next.Serve(params) + next.Serve(nil, nil, params) }) }) // Add route with specific middleware api.WithMiddleware(func(next Handler) Handler { - return NewHandler(func(params []string) { + return Handler(func(w Res, r Req, params []string) { order = append(order, 2) - next.Serve(params) + next.Serve(nil, nil, params) }) }).Get("/users", func(w Res, r Req, params []string) { order = append(order, 3) @@ -366,7 +354,7 @@ func TestGroup(t *testing.T) { h, params, found := r.Lookup("GET", "/api/users") assert.True(t, found) - h.Serve(params) + h.Serve(nil, nil, params) // Check middleware execution order assert.Equal(t, len(order), 3) @@ -465,8 +453,8 @@ func BenchmarkWildcardLookup(b *testing.B) { func BenchmarkMiddleware(b *testing.B) { passthrough := func(next Handler) Handler { - return NewHandler(func(params []string) { - next.Serve(params) + return Handler(func(w Res, r Req, params []string) { + next.Serve(nil, nil, params) }) } @@ -477,7 +465,7 @@ func BenchmarkMiddleware(b *testing.B) { b.ResetTimer() for i := 0; i < b.N; i++ { h, params, _ := r.Lookup("GET", "/test") - h.Serve(params) + h.Serve(nil, nil, params) } }) @@ -489,7 +477,7 @@ func BenchmarkMiddleware(b *testing.B) { b.ResetTimer() for i := 0; i < b.N; i++ { h, params, _ := r.Lookup("GET", "/test") - h.Serve(params) + h.Serve(nil, nil, params) } }) @@ -503,7 +491,7 @@ func BenchmarkMiddleware(b *testing.B) { b.ResetTimer() for i := 0; i < b.N; i++ { h, params, _ := r.Lookup("GET", "/test") - h.Serve(params) + h.Serve(nil, nil, params) } }) } @@ -537,8 +525,8 @@ func BenchmarkGroups(b *testing.B) { r := New() api := r.Group("/api") api.Use(func(next Handler) Handler { - return NewHandler(func(params []string) { - next.Serve(params) + return Handler(func(w Res, r Req, params []string) { + next.Serve(nil, nil, params) }) }) v1 := api.Group("/v1") @@ -547,7 +535,7 @@ func BenchmarkGroups(b *testing.B) { b.ResetTimer() for i := 0; i < b.N; i++ { h, params, _ := r.Lookup("GET", "/api/v1/users") - h.Serve(params) + h.Serve(nil, nil, params) } }) }