clojure - 您如何使用 Reitit 在 Clojure 中设置中间件以启用主体参数的强制转

我正在尝试设置一个执行强制的 Reitit 路由器。我可以让响应部分正常工作,但我似乎无法让 body 强制正常工作。以下是我使用的代码:

(ns example
  (:require
   [ring.middleware.json :refer [wrap-json-body wrap-json-response]]
   [ring.middleware.reload :refer [wrap-reload]]
   [ring.util.response :refer [response]]
   [reitit.ring.coercion :as rrc]
   [reitit.coercion.malli]
   [reitit.ring :as ring]))

(def router
  (ring/ring-handler
   (ring/router
    [["/healthz" {:get (fn [_] {:status 200 :body "healthy"})}]
     ["/api" {:coercion reitit.coercion.malli/coercion
              :middleware [rrc/coerce-exceptions-middleware
                           rrc/coerce-request-middleware
                           rrc/coerce-response-middleware]}
      ["/messages" {:post {:summary "Add a new message"
                           :parameters {:body [:map [:name string?]]}
                           :responses {200 {:body [:map
                                                   [:message string?]]}}
                           :handler (fn [req]
                                      {:status 200 :body {:message (:name (:body req))}})}}]]]
    {:data {:middleware []}})
   (ring/create-default-handler)))

(def app (-> #'router
             (wrap-reload)
             (wrap-json-response)
             (wrap-json-body {:keywords? true :bigdecimals? true})))

即使我发送正确的正文参数并出现以下错误,强制也会失败:

{
  "schema": "[:map {:closed true} [:name string?]]",
  "errors": [
    {
      "path": [],
      "in": [],
      "schema": "[:map {:closed true} [:name string?]]",
      "value": null,
      "type": "malli.core/invalid-type",
      "message": "invalid type"
    }
  ],
  "value": null,
  "type": "reitit.coercion/request-coercion",
  "coercion": "malli",
  "in": [
    "request",
    "body-params"
  ],
  "humanized": [
    "invalid type"
  ]
}

这似乎表明强制转换找不到任何正文参数。我认为这与我设置中间件的方式有关,但我似乎无法解决这个问题。我应该如何设置中间件,以便 Reitit 强制在这种情况下正常工作?

最佳答案

通过删除 wrap-json-response 和 wrap-json-body 中间件并将其替换为 muuntaja 中间件,我能够使强制工作正常工作,如下所示:

(def router
  (ring/ring-handler
   (ring/router
    [["/healthz" {:get (fn [_] {:status 200 :body "healthy"})}]
     ["/api" {:coercion reitit.coercion.malli/coercion
              :middleware []}
      ["/messages" {:name ::message
                    :post {:summary "Add a new message"
                           :parameters {:body [:map [:name string?]]}
                           :responses {200 {:body [:map
                                                   [:message string?]]}}
                           :handler (fn [{:keys [parameters]}]
                                      {:status 200 :body {:message (:name (:body parameters))}})}}]]]
    {:data {:muuntaja m/instance
            :middleware [params/wrap-params
                         muuntaja/format-middleware
                         rrc/coerce-exceptions-middleware
                         rrc/coerce-request-middleware
                         rrc/coerce-response-middleware]}})
   (ring/create-default-handler)))

关于clojure - 您如何使用 Reitit 在 Clojure 中设置中间件以启用主体参数的强制转换?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60572641/

相关文章:

r - 按列汇总 : mean and sum

reactjs - 功能组件在 setState 更新 Hook 后不重新渲染

amazon-web-services - AWS CLI : Could not connect

flutter - 如何在 flutter, android studio 中不生成红色框,

python - 在 hvplot 中自定义标记列表

git - 将 git 命令与 Google Cloud Builder 结合使用

Django - 检查两个密码哈希是否具有相同的原始密码

javascript - Vue-Apexcharts 饼图总数不显示

r - 如何在 R 中绘制用 kmeans 获得的簇的 3D 图?

pandas - 在 Pandas 中使用带有多索引的聚合