bidi
bidi copied to clipboard
identical routes w/different request-methods - first wins
Not sure if this is part of the design or not but I was surprised to find that bidi won't match a route if a previous route has the same path:
(bidi/match-route
[["users" "/" [#"[^/]+" :id]] {:delete :delete-handler}
["users" "/" [#"[^/]+" :id]] {:put :update-handler}] "users/1" :request-method :put)
^^ yields nil
Not that one would normally construct routes like that. I just stumbled on this while dynamically building routes from a mapping.
- Matt
This works for me:
(def routes
["/" [["api/" {"users" {"" {:get :api.users/list
:post :api.users/create}}}]]])
(bidi.bidi/match-route routes "/api/users" :request-method :get)
; => {:handler :api.users/list, :request-method :get}
(bidi.bidi/match-route routes "/api/users" :request-method :post)
; => {:handler :api.users/create, :request-method :post}
But readme never mentions you could call match-route with more than 2 arguments. I think it'd be great to have this in readme.
EDIT: I just realized my problem wasn't the same as @mwmitchell had. For his problem solution would be
(bidi.bidi/match-route
[["users" "/" [#"[^/]+" :id]] {:delete :delete-handler,
:put :update-handler}]
"users/1" :request-method :put)
; => {:route-params {:id "1"}, :handler :update-handler, :request-method :put}
Yes, there shouldn't be duplicate routes that differ only by method. The method is not part of a URI, and the URI should uniquely identify a resource. In my opinion, it helps if the routing library encourages this. The use of method keyword guards is really an advanced feature to help when it is really needed (migrating from Compojure).