This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2022-01-13
Channels
- # admin-announcements (1)
- # announcements (40)
- # aws (2)
- # babashka (46)
- # babashka-sci-dev (106)
- # beginners (31)
- # cider (5)
- # circleci (2)
- # clj-kondo (48)
- # clojure (118)
- # clojure-belgium (1)
- # clojure-chicago (3)
- # clojure-europe (19)
- # clojure-ireland (3)
- # clojure-losangeles (2)
- # clojure-nl (2)
- # clojure-spec (10)
- # clojure-uk (4)
- # clojurescript (18)
- # community-development (5)
- # core-async (159)
- # cursive (16)
- # datomic (16)
- # etaoin (1)
- # fulcro (21)
- # funcool (14)
- # graalvm (5)
- # gratitude (4)
- # holy-lambda (28)
- # jobs (1)
- # jobs-discuss (1)
- # kaocha (1)
- # lsp (12)
- # malli (21)
- # meander (12)
- # music (1)
- # off-topic (8)
- # portal (5)
- # react (18)
- # reitit (1)
- # releases (4)
- # remote-jobs (1)
- # shadow-cljs (56)
- # timbre (4)
Hey everyone. I’m still getting the hang of reitit (which I really
like so far). I have just realized that my responses don’t seem to
be coerced (requests are, though). I’m using
reitit.coercion.schema
and muuntaja
. Below is part of an
example (please ask if you need more details), which shows that
responses are not coerced. I would be super happy if someone had
the time to try and explain what I’m doing wrong here.
From the router:
...
(ring/ring-handler
(ring/router
[["/" (handle-index config)]
...
["/api"
{:swagger {:tags ["api"]}}
(make-endpoints run-m)]]
{:data {:muuntaja m/instance
:coercion schema/coercion
:middleware [swagger/swagger-feature
;; query-params & form-params
parameters/parameters-middleware
;; content-negotionation, request and
;; response en-/decoding.
muuntaja/format-middleware
;; exception handling
wrap-exception
;; coercing response bodys
coercion/coerce-response-middleware
;; coercing request parameters
coercion/coerce-request-middleware
;; multipart
multipart/multipart-middleware
wrap-request-logger
wrap-ignore-cors]}})
(ring/routes
(swagger-ui/create-swagger-ui-handler
{:path "/api"
:config {:validatorUrl nil
:operationsSorter "alpha"}})
(ring/create-default-handler)))
...
And the code that triggers the exception:
(let [port (find-free-port)
config (active-config/make-configuration config/schema [] {:webserver {:port port}})
make-endpoints (fn [_]
["/test-endpoint"
{:get {:parameters {:query {:id s/Uuid
:number s/Int
:string s/Str}}
:responses {200 {:body {:id s/Uuid
:number s/Int
:string s/Str}}}
:handler
(fn [{{{:keys [id number string]} :query} :parameters}]
{:status 200
:headers {"Content-Type" "application/json"}
:body {:id id
:number number
:string string}})}}])
{:keys [id number string]}
{:id (effect/get-uuid!), :number 42, :string "string"}]
(try
(webserver/init-server! config ... make-endpoints)
(let [{:keys [headers status body] :as resp}
(http-client/get (str ":" port "/api/test-endpoint")
{:accept :json
:query-params {:id (util/show-uuid id)
:number number
:string string}})]
(t/is (= (json/generate-string {:id (util/show-uuid id)
:number number
:string string})
body)))
...
(finally (webserver/stop-server!))))
Which results in the following exception (which makes me belive the
coercion of the response map never takes place):
...
:body
"{\n\"cause0\":\"java.lang.IllegalArgumentException: No implementation of method: :write-body-to-stream of protocol: #'ring.core.protocols/StreamableResponseBody found for class: clojure.lang.PersistentArrayMap\",\n\"message\":\"java.lang.IllegalArgumentException: No implementation of method: :write-body-to-stream of protocol: #'ring.core.protocols/StreamableResponseBody found for class: clojure.lang.PersistentArrayMap\",\n\"url\":\"/api/test-endpoint\",\n\"status\":\"500\"\n}",
...