Skip to content

PR for middleware support #293

Closed
Closed
@nadiamoe

Description

Hello there,

I've been using gorilla/mux for a while on an internal project at my organization, and due to some requirements, I ended up forking the project and adding some extra features, such as internal support for middleware.

Yes, I am aware that negroni is a thing, and that it also provides this functionality. However, there are a few key things you can't do just chaining mux after your middleware:

  • Acting only if a route match is found: Waiting to see if a route actually matches before acting allows for more flexibility and coherent design. For example, an authentication middleware can happily return 403 if the required credentials are not supplied, and at the same time a normal 404 will be returned by mux if the route does not exist. This option does not exist if you need to process authentication headers before the request is matched.

  • Adding middleware for subrouters is simpler if it is embed inside mux.

  • It is more efficient. If your site receives heavy traffic and your middleware performs heavy tasks, you'll appreciate this kind of saving.

After pondering a bit, I decided that this simple addon was worth implementing, so I did.

As a middleware needs to be able to stop the handlers chain, I implemented it using a slightly modified http.Handler interface:

type Middleware interface {
	ServeHTTP(http.ResponseWriter, *http.Request) (http.ResponseWriter, *http.Request)
}

type MiddlewareFunc func(http.ResponseWriter, *http.Request) (http.ResponseWriter, *http.Request)

If the middleware implementations return nil as either http.ResponseWriter or *http.Request the chain is stopped. Also, http.ResponseWriter and *http.Request can be hijacked if the middleware wants to. This is an approach slightly different to negroni's, where a third parameter of *http.HandlerFunc is added. I thought this way were better as it simplifies greatly building and iterating the middleware chain. Also, I don't like recursion. Of course, wrapper functions which receive http.Handler and http.HandlerFunc exists, so standard handlers can be chained too.

I'm not sure if you think this feature is kind of out-of scope. But if you don't, I'll happily open a PR and discuss any modifications or style changes you'd want to be done.

Activity

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

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions