I am designing my handlers to return a http.Handler. Here's the design of my handlers:
func Handler() http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
})
}
My middleware is designed to accept an http.Handler and then call the handler once the middleware has finished performing its operations. Here's the design of my middleware:
func Middleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// Middleware operations
next.ServeHTTP(w, r)
})
}
Considering the design of my middleware and handlers, what is the proper way of passing information from the middleware to the handler? The information that I am trying to pass from my middleware to the handlers is a JSON web token parsed from the request body. If I do not pass the parsed JWT to the handler, then I will need to parse the JWT again in my handlers. Parsing the request body for a JWT in both the middleware and handler seems wasteful. Just in case this information is relevant, I am using the standard net/http library with gorilla mux.
Since you're already using Gorilla take a look at the context package.
(This is nice if you don't want to change your method signatures.)
import (
"github.com/gorilla/context"
)
...
func Middleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// Middleware operations
// Parse body/get token.
context.Set(r, "token", token)
next.ServeHTTP(w, r)
})
}
...
func Handler() http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
token := context.Get(r, "token")
})
}
The Gorilla context
package is now in maintenance mode
per the repo:
Note gorilla/context, having been born well before context.Context existed, does not play well with the shallow copying of the request that http.Request.WithContext (added to net/http Go 1.7 onwards) performs.
Using gorilla/context may lead to memory leaks under those conditions, as the pointers to each http.Request become "islanded" and will not be cleaned up when the response is sent.
You should use the http.Request.Context() feature in Go 1.7.
The proper way to pass request scoped data would now be the context package in the standard library.
https://golang.org/pkg/context/
You can access it with request.Context on an http.Request.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With