I was looking into both Aleph server and client finally
(after http-kit, clj-json, HTTPUrlConnection, etc)
I can't find an example showing how to implement a typical JSON API
and how should I talk to one using the aleph http client.
I looked into the source and as I see it supposed to respond with the value of cheshire.core/encode
which is a string in newer versions, but I'm getting a java.io.ByteArrayInputStream
instead.
That input stream indeed contains the JSON string, which I've passed in via aleph.http/request
and it was coerced from the :form-params
field because I specified the :content-type :application/json
in the request map.
@(http/request
{:request-method :post
:url "<http://localhost:8080/set-session.json>"
:content-type :application/json
:form-params {:test 1234}
:as :json
:cookie-store jar
:connection-timeout 1000
:request-timeout 2000})
Do I understand well, that parsing the request body within an aleph.http.server
is the responsibility of the ring middleware it is serving?
If that's the case, what's the recommended ring middleware to deal with this?
It seems like ring.core
doesn't provide any and googling yields a bunch of alternatives:
• ring.middleware.json/wrap-json-params
from ring/ring-json
• weavejester/ring-json-response
• ngrunwald/ring-middleware-format
and it's modern incarnation muuntaja.middleware/wrap-format
from metosin/muuntaja
• ring-clojure/ring-json
Putting all this together is such a patchwork compared to other language ecosystems, it makes me suspicious that I'm doing something wrong... 😕 Please enlighten me if that's the case!
@onetom for an http/json api you might want to look at #yada which layers a lot of http handling stuff on top of aleph, and includes nice things like swagger generation, schema-based coercion (from json's limited types to clojure's richer types) and async multipart handling
@onetom I think muuntaja.middleware/wrap-format
should do the job. Does it work for you?
@dimovich im trying the reitit.ring.middleware.muuntaja/format-middleware
, since i've just switched to reitit
, but currently i have routing issues, so i can't confirm whether it works or not
thanks! i haven't realized it's also based on aleph. i would consider it then, though the reitit approach feels so much nicer and general and flexible and everything 🙂
@onetom updated the reitit-http
swagger example to run with aleph, just comment the jetty out and aleph in: https://github.com/metosin/reitit/tree/master/examples/http-swagger. There is also example routes for files & async values via Manifold. Reitit doesn’t ship with any default interceptor stack, but the example has a bare-bones api-stack included.
thanks!
i was studying that example earlier, but it's a bit hard to follow without navigating around the source with some proper clojure editor.
for example both the ring/router
and the ring/ring-handler
accept options, but extra middlewares i supply to the ring/ring-handler
, but the example only shows interceptors within a {:data {:interceptors ...}}
structure of the http/routes
function
the indentation is not deep enough to immediately see which option block belongs to which function.
so im still a bit confused because of the lot of similar names...
the source code is really clear though, so even without more documentation and examples i could figure out a lot of it myself. your conference talk also helped a lot! you reminded me that i can just test the middleware functions directly first; i don't need them into a webserver necessarily
the screenshot on the https://metosin.github.io/reitit/ring/transforming_middleware_chain.html page is showing middleware names. is that really what im supposed to see if i do
(defn router []
(reitit.ring/router
[["/test" {:get test-route}]
{:reitit.middleware/transform print-request-diffs}))
?
i only see a request and a response; nothing about middlewares, although i have the following handler:
(def app
(reitit.ring/ring-handler
(router)
(reitit.ring/create-default-handler)
{:middleware
[muuntaja/format-middleware
ring.middleware.cookies/wrap-cookies
[ring.middleware.session/wrap-session
{:store (ring.middleware.session.memory/memory-store sessions)}]]}))
let’s continue on #reitit
sorry, i thought i was on #reitit 🙂