路径前缀子路由器与个别处理程序

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

PathPrefixed Subrouter with individual handlers

问题

给定以下代码(完整示例请参见Go playground):

// Collection
root := r.PathPrefix("/widgets/").Subrouter()
root.Methods("POST").Handler(h.Create)

// Individual
object := root.PathPrefix("/{uuid}").Subrouter()
// ~neither: object := root.PathPrefix("/{uuid}").Subrouter() 
object.Methods("GET").Handler(h.Show)
object.Methods("PUT").Handler(h.Replace)
object.Methods("DELETE").Handler(h.Delete)

// Relationships
object.Methods("GET").Path("/foos").Handler(eh.Foos)
object.Methods("GET").Path("/bars").Handler(eh.Bars)

我本来期望以下URL将触发相应的处理程序,但似乎无法使其工作:

  • ✔ POST /widgets => h.Create
  • ✔ GET /widgets/123 => h.Show (假设 PathPrefix('/{uuid}'))
  • ✔ GET /widgets/123/ => h.Show (如果有 'PathPrefix('/{uuid}/')' 则需要)
  • ✖ GET /widgets/123/foos => h.Foos (实际上路由到了 h.Show)
  • ✖ GET /widgets/123/bars => h.Bars (实际上路由到了 h.Show)

不幸的是,最后两个URL似乎都无法路由,它们都触发了 h.Show。有人能指出我做错了什么吗?我本来期望一个没有尾部斜杠的无界限 {uuid} 可以忽略 / 继续运行,但事实并非如此。

我甚至不知道这是否与 Subrouter 的 strict-slash 问题有关,该问题在 Github 上仍然未解决(#31),但据我所了解,我尝试了其中的替代方法(即 object.Methods("GET").Path("/").Handler(h.Show))。

通过 Methods()object 根上挂载的处理程序是否会阻止任何进一步匹配的路由?

英文:

Given the following (complete example at Go playground):

// Collection
root := r.PathPrefix("/widgets/").Subrouter()
root.Methods("POST").Handler(h.Create)

// Individual
object := root.PathPrefix("/{uuid}").Subrouter()
// ~neither: object := root.PathPrefix("/{uuid}").Subrouter() 
object.Methods("GET").Handler(h.Show)
object.Methods("PUT").Handler(h.Replace)
object.Methods("DELETE").Handler(h.Delete)

// Relationships
object.Methods("GET").Path("/foos").Handler(eh.Foos)
object.Methods("GET").Path("/bars").Handler(eh.Bars)

I would have expected the following URLs to trigger the respective handlers, but I can't seem to make it work:

✔ POST /widgets          => h.Create
✔ GET  /widgets/123      => h.Show    (assumes PathPrefix('/{uuid}'))
✔ GET  /widgets/123/     => h.Show    (required if 'PathPrefix('/{uuid}/')')
✖ GET  /widgets/123/foos => h.Foos    (actually routes h.Show)
✖ GET  /widgets/123/bars => h.Bars    (actually routes h.Show)

Unfortunately neither of the last two are apparently routable, they both trigger h.Show, can anyone point out what I'm doing wrong? I might have expected that having an unbounded {uuid} (without the trailing slash) could have run-on, ignoring the / but that doesn't seem to be the case.

I don't even know if this has to do with the Subrouter strict-slash issue which is still open on Github (#31), but to the best of my understanding I did try the alternatives there. (i.e object.Methods("GET").Path("/").Handler(h.Show))

Could the Handler mounted on the object root via Methods() prevent any further routes matching?

答案1

得分: 2

问题在于gorilla/mux会触发第一个匹配的处理程序。这一点非常重要,因为它会匹配到第一个匹配的处理程序

这意味着逻辑上位于 /{id}/ 下的路由永远不会被找到,因为匹配它们的路由会首先被父处理程序匹配到。

将代码更改为以下内容可以按预期工作:

// 集合
root   := r.PathPrefix("/widgets/").Subrouter()
object := root.PathPrefix("/{uuid}").Subrouter()

// 关系
object.Methods("GET").Path("/foos").Handler(eh.Foos)
object.Methods("GET").Path("/bars").Handler(eh.Bars)

// 单个
root.Methods("POST").Handler(h.Create)
object.Methods("GET").Handler(h.Show)
object.Methods("PUT").Handler(h.Replace)
object.Methods("DELETE").Handler(h.Delete)

然后一切都可以正常工作。

英文:

The problem was that gorilla/mux fires the first matching handler. That's important the first matching handler.

That means that routes logically under /{id}/ are never found, since the routes that would match them are matched first by the parent handler.

Changing the code to the following makes it work as expected:

// Collection
root   := r.PathPrefix("/widgets/").Subrouter()
object := root.PathPrefix("/{uuid}").Subrouter()

// Relationships
object.Methods("GET").Path("/foos").Handler(eh.Foos)
object.Methods("GET").Path("/bars").Handler(eh.Bars)

// Individual
root.Methods("POST").Handler(h.Create)
object.Methods("GET").Handler(h.Show)
object.Methods("PUT").Handler(h.Replace)
object.Methods("DELETE").Handler(h.Delete)

Then things work perfectly.

huangapple
  • 本文由 发表于 2015年3月3日 15:16:02
  • 转载请务必保留本文链接:https://go.coder-hub.com/28826101.html
匿名

发表评论

匿名网友

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

确定