I'm coming from node express, and I was able to pass in as many middleware as possible, for example: routes.use('/*', ensureAuth, logImportant, ... n);
How can I do something similar when using r.GET("/", HomeIndex)
?
Am I forced to do something like EnsureAuth(HomeIndex)
? Because I can get that to work. Unfortunately, I'm not sure what would be a good way to add as many middlewares as I want without chaining functions together.
Is there a more elegant way so I could somehow use variadic type function to do r.GET("/", applyMiddleware(HomeIndex, m1, m2, m3, m4)
? I'm trying that out right now, but I feel like there's a better way to do this.
I've looked at the httprouter issues page, can't find anything :(
Thanks!
Here is an example how I did it:
package main
import (
"context"
"fmt"
"log"
"net/http"
"github.com/julienschmidt/httprouter"
"github.com/justinas/alice"
)
// m1 is middleware 1
func m1(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
//do something with m1
log.Println("m1 start here")
next.ServeHTTP(w, r)
log.Println("m1 end here")
})
}
// m2 is middleware 2
func m2(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
//do something with m2
log.Println("m2 start here")
next.ServeHTTP(w, r)
log.Println("m2 end here")
})
}
func index(w http.ResponseWriter, r *http.Request) {
// get httprouter.Params from request context
ps := r.Context().Value("params").(httprouter.Params)
fmt.Fprintf(w, "Hello, %s", ps.ByName("name"))
}
// wrapper wraps http.Handler and returns httprouter.Handle
func wrapper(next http.Handler) httprouter.Handle {
return func(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
//pass httprouter.Params to request context
ctx := context.WithValue(r.Context(), "params", ps)
//call next middleware with new context
next.ServeHTTP(w, r.WithContext(ctx))
}
}
func main() {
router := httprouter.New()
chain := alice.New(m1, m2)
//need to wrap http.Handler to be compatible with httprouter.Handle
router.GET("/user/:name", wrapper(chain.ThenFunc(index)))
log.Fatal(http.ListenAndServe(":9000", router))
}
Link to code (you can't run it from play.golang.org
though): https://play.golang.org/p/BOCt97xcoY