r := mux.NewRouter() // Single handler r.HandleFunc("/form", use(http.HandlerFunc(formHandler), csrf, logging) // All handlers http.Handle("/", recovery(r)) // Sub-routers apiMiddleware := []func(http.Handler) http.Handler{logging, apiAuth, json} api := router.PathPrefix("/api").SubRouter() api.Handle("/users", use(usersHandler, apiMiddleware...)) // Middleware chainer func use(h http.Handler, middleware ...func(http.Handler) http.Handler) http.Handler { for _, m := range middleware { h = m(h) } return h } // Middleware (just a http.Handler) func csrf(h http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { // do stuff h.ServeHTTP(w, r) // do stuff after }) } // Basic handler at the end of it all. func formHandler(w http.ResponseWriter, r *http.Request) { // do stuff }