Compojure-未提供所需参数时如何返回404?

Kon*_*rus 3 clojure compojure

假设我有这个处理程序:

(defroutes routes
  (DELETE    "/books"      [id]              (delete-book id)))
Run Code Online (Sandbox Code Playgroud)

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

Mic*_*zyk 6

首先,您可以将其id作为URI的一部分,它看起来不错并且是RESTful的,并允许您使用route语法施加条件:

(GET ["/books/:id" :id #"[0-9]+"] [] ...)
Run Code Online (Sandbox Code Playgroud)

如果您确实喜欢使用参数,则类似

(if-not id
  (ring.util.response/not-found body-for-404)
  ...)
Run Code Online (Sandbox Code Playgroud)

应该可以在下一个Ring版本中使用,尽管该特定功能尚未发布({:status 404 :headers {} :body the-body}尽管只是返回了)。

也,

(when id
  ...)
Run Code Online (Sandbox Code Playgroud)

将导致等效的路由匹配失败,并尝试其余路由;那么你可以使用

(compojure.route/not-found body-for-404)
Run Code Online (Sandbox Code Playgroud)

作为始终匹配的最终路线。

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

(defn wrap-404 [handler]
  (fn wrap-404 [request]
    (when (-> request :params :id)
      (handler request))))
Run Code Online (Sandbox Code Playgroud)

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