Reputation: 54045
Suppose I have this handler:
(defroutes routes
(DELETE "/books" [id] (delete-book id)))
What can I do to make this app return HTTP 404 when request does not contain ID?
Upvotes: 4
Views: 2439
Reputation: 84369
Firstly, you could make the id
a part of the URI, which seems nice and RESTful and would allow you to use the route syntax to impose your condition:
(GET ["/books/:id" :id #"[0-9]+"] [] ...)
If you do prefer to use a parameter, something like
(if-not id
(ring.util.response/not-found body-for-404)
...)
should work in the next Ring version, though this particular function has not been released yet (it simply returns {:status 404 :headers {} :body the-body}
though).
Also,
(when id
...)
would result in the equivalent of a route match failure and the remaining routes would be tried; then you could use
(compojure.route/not-found body-for-404)
as the final route which would always match.
Finally, if you wish to apply filtering to a large group of Compojure handlers, you may wish to combine them into a single handler with Compojure's defroutes
or routes
(the latter is a function) and wrapping them in a piece of middleware:
(defn wrap-404 [handler]
(fn wrap-404 [request]
(when (-> request :params :id)
(handler request))))
You can then include the wrapped handler as an entry in routes
/ defroutes
forms.
Upvotes: 7