嵌套子路由器在Gorilla Mux中的实现

huangapple go评论85阅读模式
英文:

Nesting subrouters in Gorilla Mux

问题

我一直在使用gorilla/mux来处理我的路由需求。但是我注意到一个问题,当我嵌套多个子路由时,它不起作用。

这是一个例子:

func main() {
    r := mux.NewRouter().StrictSlash(true)
    api := r.Path("/api").Subrouter()
    u := api.Path("/user").Subrouter()
    u.Methods("GET").HandleFunc(UserHandler)
    http.ListenAndServe(":8080", r)
}

我希望使用这种方法,这样我就可以将路由的填充委托给其他包,例如user.Populate(api)

然而,这似乎不起作用。只有在链中使用单个子路由时才起作用。

有什么想法吗?

英文:

I've been using gorilla/mux for my routing needs. But I noticed one problem, when I nest multiple Subrouters it doesn't work.

Here is the example:

func main() {
    r := mux.NewRouter().StrictSlash(true)
    api := r.Path("/api").Subrouter()
    u := api.Path("/user").Subrouter()
    u.Methods("GET").HandleFunc(UserHandler)
    http.ListenAndServe(":8080", r)
}

I wanted to use this approach so I can delegate populating the router to some other package, for example user.Populate(api)

However this doesn't seem to work. It works only if I use single Subrouter in the chain.

Any ideas?

答案1

得分: 36

我明白了,所以我会将翻译好的内容返回给你。以下是翻译的结果:

我找到解决方法了,所以我会在这里发布,以防有人和我一样愚蠢。 嵌套子路由器在Gorilla Mux中的实现

当创建基于路径的子路由时,你必须使用PathPrefix而不是Path来获取它。

r.PathPrefix("/api").Subrouter()

只有在将处理程序附加到该端点时才使用r.Path("/api")

英文:

I figured it out, so I'll just post it here in case someone is as stupid as I was. 嵌套子路由器在Gorilla Mux中的实现

When creating path-based subrouter, you have to obtain it with PathPrefix instead of Path.

r.PathPrefix("/api").Subrouter()

Use r.Path("/api") only when attaching handlers to that endpoint.

答案2

得分: 1

对于那些在授权(auth)和非授权(noauth)路由之间犹豫不决的人,以下方法对我来说效果很好:

r := mux.NewRouter()

noAuthRouter := r.MatcherFunc(func(r *http.Request, rm *mux.RouteMatch) bool {
    return r.Header.Get("Authorization") == ""
}).Subrouter()

authRouter := r.MatcherFunc(func(r *http.Request, rm *mux.RouteMatch) bool {
    return true
}).Subrouter()

然后,你可以只为 authRouter 应用中间件。

英文:

For those who are struggling to split between auth and noauth routes, the following works fine for me:

r := mux.NewRouter()

noAuthRouter := r.MatcherFunc(func(r *http.Request, rm *mux.RouteMatch) bool {
	return r.Header.Get("Authorization") == ""
}).Subrouter()

authRouter := r.MatcherFunc(func(r *http.Request, rm *mux.RouteMatch) bool {
	return true
}).Subrouter()

Then you can apply middleware for authRouter only

答案3

得分: -1

如果你需要将UI和API路由器分开,你可以简单地按照OP的建议进行操作:

appRouter := r.PathPrefix("/").Subrouter()
appRouter.Use(myAppRouter)
apiRouter := r.PathPrefix("/api").Subrouter()
apiRouter.Use(myAPIRouter)

非常感谢OP提供的答案。希望将所有内容放在一个地方对我的使用场景有所帮助。

英文:

If you need to Separate out the UI and API routers, you can simply do what the OP suggested:

appRouter := r.PathPrefix("/").Subrouter()
appRouter.Use(myAppRouter)
apiRouter := r.PathPrefix("/api").Subrouter()
apiRouter.Use(myAPIRouter)

Many thanks for the OP for providing the answer. Hopefully having it all in one place for my use case will help someone.

huangapple
  • 本文由 发表于 2015年4月11日 16:53:48
  • 转载请务必保留本文链接:https://go.coder-hub.com/29575972.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定