3

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

Gurleen Sethi
  • 3,162
  • 6
  • 26
  • 48

3 Answers3

4

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.

blackgreen
  • 34,072
  • 23
  • 111
  • 129
0

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.

joelthegraf
  • 116
  • 6
0

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.

Chandan
  • 11,465
  • 1
  • 6
  • 25