compojure-api 允许您定义return
模式:
(s/defschema Pizza
{:name s/Str})
(GET "/pizza/:id" [id]
:return Pizza
:summary "returns a Pizza"
(ok (get-pizza id)))
我的问题是当 get-pizza
fn 返回 404 {:status 404 :body {:message "Invalid id provided"}}
响应(对请求者)是该 404 与Pizza
架构不匹配:
{
"errors": {
"name": "missing-required-key",
"status": "disallowed-key",
"body": "disallowed-key"
}
}
文档显示您可以提供多个响应模式,但我不清楚我的 get-pizza
fn 应该返回什么才能利用这些模式。他们的示例使用 ring-http-response lib 来生成返回值,但我的 get-pizza
返回值和 ring-http-response 'not found' fn 之间没有区别。
老实说,如果可能的话,我宁愿不使用:responses
参数,因为我已经可以预见所有代码重复。在指定:return
架构之前,我能够让我的 get-pizza
fn 返回 404 并正确传递给请求者,但是一旦我添加了架构,我就无法再这样做了。我考虑过将返回值:return (s/one Pizza Error)
其中Error
将是通用定义的错误映射,但我不明白如果理论上所有调用都可以返回 500,为什么我会为每个路由执行此操作。
注意:我改用:return
参数的原因是,它使生成的 swagger-ui 文档更漂亮、更易于理解。
我认为您的代码中有一个小问题,因为您没有显示get-pizza [id]
函数的实现。
您返回{:status 404 :body {:message "Invalid ID provided}}
然后由 (ok (get-pizza id))
包装到 HTTP 200 响应中。
您的get-pizza
函数应返回披萨或 nil(如果未找到)。您的 HTTP 响应应根据路由中的响应生成:
(GET "/:id" []
:path-params [id :- Long]
:return Pizza
:summary "Gets a pizza"
(if-let [pizza (get-pizza id)]
(ok pizza)
(not-found {:message "Invalid ID provided"})))
来自 compojure-api repo 的原始示例具有略有不同的实现,对于来自get-pizza
的nil
值,它仍将返回具有空响应正文的 HTTP 200 响应。根据您的问题,您将返回 404,上面的代码应该满足您的要求。