Clojure Compojure-如果未提供所需的参数,如何返回404?

Clojure Compojure-如果未提供所需的参数,如何返回404?,clojure,compojure,Clojure,Compojure,假设我有这个处理器: (defroutes routes (DELETE "/books" [id] (delete-book id))) 当请求不包含ID时,如何使此应用程序返回HTTP 404?首先,您可以将ID作为URI的一部分,这看起来很好,而且是RESTful的,并允许您使用路由语法来施加您的条件: (GET ["/books/:id" :id #"[0-9]+"] [] ...) 如果您确实喜欢使用参数,类似 (if-not id

假设我有这个处理器:

(defroutes routes
  (DELETE    "/books"      [id]              (delete-book id)))

当请求不包含ID时,如何使此应用程序返回HTTP 404?

首先,您可以将
ID
作为URI的一部分,这看起来很好,而且是RESTful的,并允许您使用路由语法来施加您的条件:

(GET ["/books/:id" :id #"[0-9]+"] [] ...)
如果您确实喜欢使用参数,类似

(if-not id
  (ring.util.response/not-found body-for-404)
  ...)
应该可以在下一个Ring版本中使用,尽管这个特定函数还没有发布(它只是返回
{:status 404:headers{}:body the body}

而且

将导致相当于路由匹配失败,剩余路由将被尝试;那你可以用

(compojure.route/not-found body-for-404)
作为最终的路线,它将永远匹配

最后,如果您希望对一大组Compojure处理程序应用过滤,您可能希望将它们与Compojure的
defroutes
routes
(后者是一个函数)组合成一个处理程序,并将它们包装在一个中间件中:

(defn wrap-404 [handler]
  (fn wrap-404 [request]
    (when (-> request :params :id)
      (handler request))))

然后,您可以在
routes
/
defroutes
表单中将包装好的处理程序作为一个条目包含在内。

是否无法自动执行此操作(例如,使用compojure宏的参数)?我讨厌对所有的路线都这么做。我用一些方法编辑了答案,让它变得干涸。我自己会选择基于URI的方法。在Compojure的DSL中,没有神奇的语法可以对参数映射的实际内容施加条件。
(defn wrap-404 [handler]
  (fn wrap-404 [request]
    (when (-> request :params :id)
      (handler request))))