【问题标题】:compojure-api return value schema or errorcompojure-api 返回值模式或错误
【发布时间】:2016-06-07 16:58:42
【问题描述】:

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"
  }
}

docs 表明您可以提供多个响应模式,但我不清楚我的get-pizza fn 应该返回什么以利用这些模式。他们的示例使用 ring-http-response 库生成返回值,但我的 get-pizzaring-http-response 'not found' fn 的返回值没有区别。

说实话,如果可能的话,我宁愿不使用:responses 参数,因为我已经可以预见到所有的代码重复。在指定 :return 架构之前,我能够让我的 get-pizza fn 返回 404 并正确传递给请求者,但是一旦我添加了架构,我就无法再这样做了。我考虑让返回值为:return (s/one Pizza Error),其中Error 将是一个通用定义的错误映射,但我不明白为什么我会为 every 路由执行此操作,如果理论上所有调用都可以返回500.

注意:我改用 :return 参数的原因是它使生成的 swagger-ui 文档更漂亮且更易于理解。

【问题讨论】:

    标签: clojure compojure plumatic-schema compojure-api


    【解决方案1】:

    我认为您的代码中有一个小问题,因为您没有显示您的 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"})))
    

    The original example from compojure-api repo 有一点不同的实现,对于来自get-pizzanil 值,它仍然会返回带有空响应主体的HTTP 200 响应。根据您的问题,您将返回 404 并且上面的代码应该满足您的要求。

    【讨论】:

    • 上述代码返回相同的错误,因为not-found 的响应与Pizza 模式的定义:return 值不匹配。当我执行(s/maybe Pizza) 时它确实有效,但是当并非所有返回值都返回 200 时,必须将 all 我的返回值包装在 s/Maybe 中似乎是不合理的。 get-pizza 存在于另一个文件中,我希望 get-pizza fn 能够返回一个 404,然后此路径定义将正确处理,并且想知道 compojure-api 是否有办法执行 and i> 仍然有一个定义的 return fn,因为它似乎不是一个不合理的用例。
    • 当返回nil 披萨时,您是否将路线定义更改为使用not-found?您可以尝试使用我的 fork 中的修改示例:git clone https://github.com/pbzdyl/compojure-apicd compojure-apigit checkout stackoverflow-35618493lein run 然后在另一个终端中:curl -v http://localhost:3000/api/pizzas/1000,您将收到 HTTP 404 和消息。
    • 您的代码中有一个错误,它没有让它运行,但使用了未找到的作品。我的问题是我想要一种方法让(get-pizza id) 返回我想要呈现的响应(状态代码和所有)。否则对于每条路线,我将不得不单独检查 200,404,409 等
    • 您能否提供更多信息,您遇到了什么错误?关于您担心让您的get-pizza 呈现整个响应 - 这样您就可以将相同的问题更深入地移动到您的代码中。现在您的处理程序使用oknot-found 生成响应,并且您希望手动生成响应作为get-pizza 函数中的映射。
    • 这是一个本地依赖问题,它现在运行!我在他们的 wiki 中找到了一个示例,该示例具有类似的方法,只是它有一个单独的 fn 包装 get-pizza,这是我将采用的方法,因为对于大多数路线,我必须处理的不仅仅是 200 和 404 @ 987654322@
    猜你喜欢
    • 2017-02-12
    • 1970-01-01
    • 2014-01-16
    • 1970-01-01
    • 2019-12-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多