Something small for you I hope, would appreciate an explanation as to why when I make a test (app {:request-method :get ...}) call to an endpoint that returns a map, I always get a ByteArrayInputStream (which is JSON when slurped), instead of just a straight edn map?
my route definition for this is
{:get {:summary "hello as a map"
:handler (fn [_] {:status 200 :body {:hello "world"}})}}
and my route-data is
{:validation ring.spec/validate
:exception ring.pretty/exception
:data {:coercion coercion.malli/coercion
:muuntaja m/instance
:middleware [openapi/openapi-feature
;; query-params & form-params
ring.parameters/parameters-middleware
;; content-negotiation
ring.muuntaja/format-negotiate-middleware
;; encoding response body
ring.muuntaja/format-response-middleware
;; exception handling
ring.exception/exception-middleware
;; decoding request body
ring.muuntaja/format-request-middleware
;; coercing response body
ring.coercion/coerce-response-middleware
;; coercing request parameters
ring.coercion/coerce-request-middleware
;; managing multipart requests
ring.multipart/multipart-middleware]}}
I'm still attempting to understand ring/reitit a little better, as im still doing a lot of copying off of examples atm, so I might have some fundamental misunderstandingsI would expect a call to this endpoint to return
{:status 200
:body {:hello "world"}}
similar to the example on reitit's github, but instead the body returns as a bytestream which is "{\"hello\":\"world\"}" when slurpedah so as i've been rubber-ducking here it looks like its due to the format-response-middleware, which i find odd as its docstring doesn't really imply that behavior? to me it reads as if it should be affected by passing an {"Accept" "<content-type>"} header but that appears to have no bearing?
Not sure if this is documented properly, and this goes through several layers, but Muuntaja (the lib doing the response body encoding) defaults to json if the request doesn't have Accept header: https://github.com/metosin/muuntaja/blob/0.6.10/modules/muuntaja/src/muuntaja/core.clj#L116
If you have the full ring handler, there isn't really case where you would want to return the clojure data structures as the http servers themselves can't use them for the response body. For unit testing... Hmm. If you don't care for testing the response encoding, you could build the handler fn you call in unit tests without this middleware.
https://github.com/metosin/reitit/blob/master/modules/reitit-middleware/src/reitit/ring/middleware/muuntaja.clj#L43-L47 This docstring could mention that in addition to the Accept headers, also the Muuntaja config (`:default-format`) also affects the result.
hmmm, when im doing a test call like
(app {:request-method :get
:uri "..."
:headers {"Accept" "application/edn"}})
is this an incorrect way to use an accept header?i actually keep having difficulty finding the reference-documentation for valid/useful keys in this request map
https://github.com/ring-clojure/ring/blob/master/SPEC.md specifies the request map
yes, that should be correct
that should return a bytestream which slurps to edn string
ah i see, i very much appreciate the help, this is still an area im less confident in
> :headers > A Clojure map of lowercased header name strings to corresponding header value strings.
lowercased, oh this has caused me much confusion
thank you for the link gratitude
Ah right. On the request side Ring spec says the should be always lower case. AFAIK on the response side it "doesn't matter" (except when you have multiple middleware that are checking for the same response header...)
Spec says to also use lower case headers names for response though
ahh that makes sense, i guess in my mind i assumed it would be sent to whatever the requisite case is, as in other webservers i've interacted with casing has been more loosey-goosey (and in stuff like Mozilla docs I always see headers written in Capital-Case)
(i personally prefer lowercase-as-default, have just been conditioned otherwise)
haha in fact right above it