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)

Тогда все работает отлично.

Другие вопросы по тегам