-
-
Notifications
You must be signed in to change notification settings - Fork 564
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Make middleware mountable on http.NewMuxer() #3415
Conversation
Thank you for the PR, that makes sense. I wonder if as an alternative we couldn't store the middlewares defined via // mux is the default Muxer implementation.
mux struct {
chi.Router
// protect access to middlewares and wildcards
lock sync.Mutex
// used to register middlewares during first Handle call
once sync.Once
// middlewares to be registered before handlers
middlewares []func(http.Handler) http.Handler
// wildcards maps a method and a pattern to the name of the wildcard
// this is needed because chi does not expose the name of the wildcard
wildcards map[string]string
}
// ...
// NewMuxer returns a Muxer implementation based on a Chi router.
func NewMuxer() ResolverMuxer {
r := chi.NewRouter()
return &mux{Router: r, wildcards: make(map[string]string), middlewares: []func(http.Handler) http.Handler{}}
}
// ...
func (m *mux) Handle(method, pattern string, handler http.HandlerFunc) {
m.once.Do(func() {
for _, mw := range m.middlwares {
m.Router.Use(m)
}
m.Router.NotFound(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
ctx := context.WithValue(req.Context(), AcceptTypeKey, req.Header.Get("Accept"))
enc := ResponseEncoder(ctx, w)
w.WriteHeader(http.StatusNotFound)
enc.Encode(NewErrorResponse(ctx, fmt.Errorf("404 page not found"))) // nolint:errcheck
}))
m.middlewares = nil
})
// ...
}
func (m *mux) Use(f func(http.Handler) http.Handler) {
if m.middlewares == nil {
m.Router.Use(f)
return
}
m.middlewares = append(m.middlewares, f)
} (note: I didn't test the code above - this is just to explain the idea) |
The idea looks good to me. I'll try to implement it.
They are all read access, right? An error occurs with no write access? (My misunderstanding?) Edit: Did you mean Implemented a |
That's great.
No misunderstanding, you are correct that concurrent reads are safe.
That's perfect, the edge case is indeed if |
Resolved by #3419 |
I added SmartRedirectSlashes middleware in #3394 based on #3385's discussion, but it couldn't be used with default
NewMuxer()
. The middleware need to be mounted at the top level of chi's router, but a router created byNewMuxer()
already mount the Not Found handler.Solve this problem by adding an argument to
NewMuxer()
.