英文:
How to nest routers in Go julienschmidt/httprouter?
问题
我想从我的服务中公开以下URL:
GET /api/foo
GET /api/bar
我还想将其结构化为嵌套在另一个路由器内部的路由器。顶级路由器将匹配所有对/api
的请求,并使用嵌套路由器为其提供服务,该嵌套路由器将匹配对/foo
和/bar
的请求。基本上,这是一种命名空间。
我可以只有一个路由器,并将/api
前缀分别添加到这两个路由上:
router.GET("/api/foo", apiFoo)
router.GET("/api/bar", apiBar)
但是,我希望能够方便地在/api
前缀下的所有路由上使用单个路由器,以便我可以通过单个函数调用为它们添加适当的中间件。
这是我尝试过的代码:
package main
import (
"log"
"net/http"
"github.com/julienschmidt/httprouter"
)
func apiFoo(w http.ResponseWriter, r *http.Request) {}
func apiBar(w http.ResponseWriter, r *http.Request) {}
func main() {
api := httprouter.New()
api.HandlerFunc(http.MethodGet, "/foo", apiFoo)
api.HandlerFunc(http.MethodGet, "/bar", apiBar)
router := httprouter.New()
router.Handler(http.MethodGet, "/api", api)
log.Fatal(http.ListenAndServe(":8080", router))
}
然而,当我访问http://localhost:8080/api/foo或http://localhost:8080/api/bar时,出现404未找到的错误。
我原以为嵌套路由器会起作用,因为路由器实现了http.Handler
接口。我漏掉了什么?
英文:
I want to expose the following URLs from my service:
GET /api/foo
GET /api/bar
I also want to structure it as a router nested inside another. The toplevel router will match all requests to /api
and serve them with the nested router which will match requests to /foo
and /bar
. Basically, namespacing.
I could just have a single router and give the /api
prefix to both the routes:
router.GET("/api/foo", apiFoo)
router.GET("/api/bar", apiBar)
But I would like the convenience of having a single router for all routes inside the /api
prefix so that I can add appropriate middlewares to them all with a single function call.
Here's what I tried:
package main
import (
"log"
"net/http"
"github.com/julienschmidt/httprouter"
)
func apiFoo(w http.ResponseWriter, r *http.Request) {}
func apiBar(w http.ResponseWriter, r *http.Request) {}
func main() {
api := httprouter.New()
api.HandlerFunc(http.MethodGet, "/foo", apiFoo)
api.HandlerFunc(http.MethodGet, "/bar", apiBar)
router := httprouter.New()
router.Handler(http.MethodGet, "/api", api)
log.Fatal(http.ListenAndServe(":8080", router))
}
However, getting 404 not found on going to http://localhost:8080/api/foo or http://localhost:8080/api/bar
I had thought that nested routers would work because routers implement the http.Handler
interface. What am I missing?
答案1
得分: 2
httprouter不会连接路径,所以你不能这样做。两个路由器只会检查请求路径并相应地处理。
有一个开放的拉取请求已经存在了7年,它将实现这个功能。你可以去那里看看,并自己实现类似的逻辑,该拉取请求是基于连接路径的。也许你可以编写一个小的辅助函数来实现这个。
如果你愿意切换路由器包,你可以考虑其他选择,比如chi,它支持路由器组。
英文:
httprouter does not concatenate the path, so you can't do it that way. Both routers will just inspect the request path and act accordingly.
There is an open pull request for 7 years, that would implement it. You could have a look there and implement similar logic yourself, the PR is based on concatenating the path. Maybe you can write a small helper function for that.
If you are willing to switch the router package, you could look into alternatives such as chi, which support router groups.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论