I am trying to set a a Reitit router that performs coercion. I can get the response section working but I can't seem to get the body coercion to work properly. The following is the code I am using:
(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})))
The coercion is failing even when I send the correct body parameters with the following error:
{
"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"
]
}
This seems to be indicating that the coercion can't find any body parameters. I assume this has to do with the way I am setting up my middleware but I can't seem to fix this. How should I set the middleware up so the Reitit coercion works properly in this case?
I was able to get coercion to work by removing the wrap-json-response and wrap-json-body middleware and replacing it with the muuntaja middleware as follows:
(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)))