Is it intended that when using coercion (-> req :body :parameters) and (-> req :body-params) differ?
I was a bit surprised that the coerced data was only in (-> req :body :parameters) .
(ns user)
(comment
(add-lib 'metosin/reitit)
(require '[muuntaja.core :as muu]
'[reitit.ring :as ring]
'[reitit.coercion.malli :as rcm]
'[reitit.ring.coercion :as rrc]
'[reitit.ring.middleware.muuntaja :as rrmm]
'[jsonista.core :as j])
(def app
(ring/ring-handler
(ring/router
[["/set"
{:post {:parameters {:body {:x [:set [:int]]}}
:responses {200 {:body {:total int?}}}
:handler (fn [{{{:keys [x]} :body} :parameters :as req}]
(println ":parameters :body" (-> req :parameters :body))
(println ":body-params" (-> req :body-params))
{:status 200
:body {:total (apply + x)}})}}]]
{:data {:muuntaja muu/instance
:coercion rcm/coercion
:middleware [rrmm/format-middleware
rrc/coerce-exceptions-middleware
rrc/coerce-request-middleware
rrc/coerce-response-middleware]}})))
(-> {:request-method :post
:uri "/set"
:headers {"content-type" "application/json"
"accept" "application/json"}
:body (java.io.ByteArrayInputStream. (j/write-value-as-bytes {:x #{1 2 3}}))}
app :body slurp j/read-value)
;; :parameters :body {:x #{1 3 2}}
;; :body-params {:x [1 3 2]}
;; => {"total" 6}
,)Yes, it is intended and coercion documentation says the coerced values will be available under :parameters.
I don't know if the decision itself has been documented somewhere.
One part is that :parameters matches the path where the schemas are defined for routes.
Another part is to be safe, as other mw might already be presuming what the body-params etc. look like. There could even be cases where you need to be able to access the non-coerced values so using different path allows keeping both avavailable.
https://github.com/metosin/reitit/blob/master/doc/ring/coercion.md > Handlers can access the coerced parameters via the :parameters key in the request.
I missed that bit in the docs, thank you π
Naive question, why itβs using a Java parser when the open api spec is json / yaml and can be read as such ?
Not a naive one at all! The main reasons are: β’ OpenAPI though being just YAML/JSON has the complexity of https://swagger.io/docs/specification/v3_0/using-ref/ which has all sorts of things like remote refs, partial refs, jsonpath resolution etc. This is quite non-trivial to implement and can have arbitrary nesting, recursive self refs etc. β’ Following the openapi spec with all its https://swagger.io/docs/specification/v3_0/data-models/data-types/ and their permutations is also non-trivial All of the above is doable by me and projects like https://github.com/oliyh/martian does it to some extent but has issues like https://github.com/oliyh/martian/issues/190. All in all the devil is in the details and keeping up with the changes in the spec is quite hard and using the official parser made sense for me. But I do plan to do that myself someday.