Skip to content

(mx *Mux) Match(...) has surprising behaviour when using (mx *Mux) Route(...) #794

Description

@msbit

If I add a subrouter using Route, calling Match with the same pattern and any method shows a (what I would consider) false positive. For example:

r := chi.NewRouter()

r.Route("/path", func(r chi.Router) {
  r.Group(func(r chi.Router) {
    r.Get("/all", nil)
  })  
}) 

I would expect:

  • r.Match(chi.NewRouteContext(), http.MethodGet, "/path") to be false, and
  • r.Match(chi.NewRouteContext(), http.MethodGet, "/path/all") to be true

however, the first case is true.

For what it's worth, the contents of the inner subrouter don't appear to matter, so:

r := chi.NewRouter()

r.Route("/path", func(chi.Router){})

shows the same behaviour in the "/path" case.

As noted this is surprising to me; I would expect no match to occur unless a final handler has been configured (Get(...), Post(...) etc).

Below is a more elaborate test setup:

package routing

import (
  "net/http"
  "testing"

  "github.com/go-chi/chi/v5"
)

func TestWithAll(t *testing.T) {
  r := chi.NewRouter()

  r.Route("/path", func(r chi.Router) {
    r.Group(func(r chi.Router) {
      r.Get("/all", nil)
    })
  })

  assert(t, !r.Match(chi.NewRouteContext(), http.MethodGet, "/path"),     "GET    /path should not be matched")
  assert(t, !r.Match(chi.NewRouteContext(), http.MethodPost, "/path"),    "POST   /path should not be matched")
  assert(t, !r.Match(chi.NewRouteContext(), http.MethodPut, "/path"),     "PUT    /path should not be matched")
  assert(t, !r.Match(chi.NewRouteContext(), http.MethodDelete, "/path"),  "DELETE /path should not be matched")
  assert(t, r.Match(chi.NewRouteContext(), http.MethodGet, "/path/all"),  "GET    /path/all should be matched")
}

func TestWithoutAll(t *testing.T) {
  r := chi.NewRouter()

  r.Route("/path", func(chi.Router){})

  assert(t, !r.Match(chi.NewRouteContext(), http.MethodGet, "/path"),     "GET    /path should not be matched")
  assert(t, !r.Match(chi.NewRouteContext(), http.MethodPost, "/path"),    "POST   /path should not be matched")
  assert(t, !r.Match(chi.NewRouteContext(), http.MethodPut, "/path"),     "PUT    /path should not be matched")
  assert(t, !r.Match(chi.NewRouteContext(), http.MethodDelete, "/path"),  "DELETE /path should not be matched")
}

func assert(t *testing.T, condition bool, message string) {
  if !condition {
    t.Errorf(message)
  }
}

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions