英文:
Difference between middleware chi.Use vs chi.With
问题
chi.Use 和 chi.With 在使用 Chi 路由器设置中间件时有什么区别?
英文:
What is the difference between chi.Use and chi.With when setting up a middleware with Chi router.
答案1
得分: 4
在同一组下的所有路由之前必须先声明Use,而r.With允许您“内联”中间件。
实际上,这两个函数的签名是不同的。Use不返回任何内容,而With返回一个chi.Router。
假设您有一个路由,并且只想向其中一个路由添加中间件,您可以使用r.With:
r.Route("/myroute", func(r chi.Router) {
r.Use(someMiddleware) // 可以在这里声明
r.Get("/bar", handlerBar)
r.Put("/baz", handlerBaz)
// r.Use(someMiddleware) // 不能在这里声明
}
r.Route("/other-route", func(r chi.Router) {
r.Get("/alpha", handlerBar)
r.Put("/beta", handlerBaz)
r.With(someMiddleware).Get("/gamma", handlerQuux)
}
在第一个示例中,someMiddleware被声明为所有子路由的中间件,而在第二个示例中,r.With允许您仅将中间件添加到/other-route/gamma路由。
英文:
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.
答案2
得分: 0
Use方法将一个中间件处理程序附加到Mux中间件堆栈。- 对于任何Mux,中间件堆栈将在搜索匹配特定处理程序的路由之前执行,这提供了在请求执行过程中提前响应、更改请求执行流程或为下一个http.Handler设置请求范围的值的机会。
With方法为端点处理程序添加内联中间件。
英文:
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.
答案3
得分: 0
使用chi.Use的用例非常简单,注册的中间件将在所有使用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)
例如:在这里,Logger中间件将在所有注册的路由处理程序之前调用。
而使用chi.With,您将在返回的新路由上运行中间件,因此如果在返回的Router上注册了任何路由,则注册的中间件将运行。这里的用例非常具体,假设您想为一组路由运行特定的中间件,或者想要为特定的路由执行某些操作,那么您可以使用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
})
})
在上面的示例中,paginate中间件仅在所有带有/articles/和/{month}-{day}-{year}的文章上调用,对于其他路由,如果在主路由上注册了任何中间件,则不会调用chi.With。
英文:
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论