PathPrefixed Subrouter с отдельными обработчиками
Учитывая следующее ( полный пример на игровой площадке Go):
// 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 (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)
К сожалению, ни один из последних двух, по-видимому, не маршрутизируется, оба h.Show
Кто-нибудь может указать, что я делаю не так? Я мог бы ожидать, что с неограниченным {uuid}
(без завершающей косой черты) может быть запущен, игнорируя /
но, похоже, это не так.
Я даже не знаю, связано ли это с проблемой строгой косой черты в Subrouter, которая все еще открыта на Github (#31), но, насколько я понимаю, я попробовал альтернативы там. (т.е. object.Methods("GET").Path("/").Handler(h.Show)
)
Может ли обработчик установлен на object
root через Methods()
предотвратить дальнейшее сопоставление маршрутов?
1 ответ
Проблема заключалась в том, что gorilla/mux
запускает первый соответствующий обработчик. Это важно для первого подходящего обработчика.
Это означает, что маршруты логически под /{id}/
никогда не найдены, так как маршруты, которые соответствуют им, сначала сопоставляются родительским обработчиком.
Изменение кода на следующий заставляет его работать как ожидалось:
// 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)
Тогда все работает отлично.