What is the difference between chi.Use
and chi.With
when setting up a middleware with Chi router.

- 3,162
- 6
- 26
- 48
3 Answers
Use
must be declared before all routes under the same group, whereas r.With
allows you to "inline" middlewares.
As a matter of fact, the function signatures are different. Use
returns nothing, With
returns a chi.Router
.
Let's say you have a route and want to add a middleware only to one of them, you would use r.With
:
r.Route("/myroute", func(r chi.Router) {
r.Use(someMiddleware) // can declare it here
r.Get("/bar", handlerBar)
r.Put("/baz", handlerBaz)
// r.Use(someMiddleware) // can NOT declare it here
}
r.Route("/other-route", func(r chi.Router) {
r.Get("/alpha", handlerBar)
r.Put("/beta", handlerBaz)
r.With(someMiddleware).Get("/gamma", handlerQuux)
}
In the first example, someMiddleware
is declared for all sub-routes, whereas in the second example r.With
allows you to add a middleware only for the /other-route/gamma
route.

- 34,072
- 23
- 111
- 129
According to the documentation of chi.Use and chi.With.
Use appends a middleware handler to the Mux middleware stack.
The middleware stack for any Mux will execute before searching for a matching route to a specific handler, which provides opportunity to respond early, change the course of the request execution, or set request-scoped values for the next http.Handler.
With adds inline middlewares for an endpoint handler.

- 116
- 6
Let see how chi.Use
and chi.With
example
The use case is pretty straight forward with chi.Use
the registered middleware will run before all the routes handler which are register with the Router
r := chi.NewRouter()
r.Use(middleware.Logger)
r.Get("/", func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("welcome"))
})
http.ListenAndServe(":3000", r)
For eg: here Logger
middleware will be called before all the register routes handler.
whereas with chi.With
you are returned new route on which the middleware would be ran so if any routes is registered on the returned Router
the registered middleware will run. Here the use case is very specific suppose if you want to run a specific middleware for a group of routes or want to perform some operation for specific routes then for the case you can use chi.Use
r.Route("/articles", func(r chi.Router) {
r.With(paginate).Get("/", listArticles) // GET /articles
r.With(paginate).Get("/{month}-{day}-{year}", listArticlesByDate) // GET /articles/01-16-2017
r.Post("/", createArticle) // POST /articles
r.Get("/search", searchArticles) // GET /articles/search
// Regexp url parameters:
r.Get("/{articleSlug:[a-z-]+}", getArticleBySlug) // GET /articles/home-is-toronto
// Subrouters:
r.Route("/{articleID}", func(r chi.Router) {
r.Use(ArticleCtx)
r.Get("/", getArticle) // GET /articles/123
r.Put("/", updateArticle) // PUT /articles/123
r.Delete("/", deleteArticle) // DELETE /articles/123
})
})
In the above example the paginate
middleware will only be called for all the articles with /articles/
and /{month}-{day}-{year}
day wise route for other routes chi.With
won't be called if there any middlware registered with chi.Use
over main route then that would be called.

- 11,465
- 1
- 6
- 25