Fork me on GitHub
#aleph
<
2019-08-30
>
onetom06:08:16

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.

onetom06:08:33

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                ""
          :content-type       :application/json
          :form-params        {:test 1234}
          :as                 :json
          :cookie-store       jar
          :connection-timeout 1000
          :request-timeout    2000})

onetom06:08:53

Do I understand well, that parsing the request body within an aleph.http.server is the responsibility of the ring middleware it is serving?

onetom06:08:01

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-jsonweavejester/ring-json-responsengrunwald/ring-middleware-format and it's modern incarnation muuntaja.middleware/wrap-format from metosin/muuntajaring-clojure/ring-json

onetom06:08:15

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!

mccraigmccraig08:08:27

@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

8
onetom09:08:25

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 🙂

dimovich08:08:10

@onetom I think muuntaja.middleware/wrap-format should do the job. Does it work for you?

onetom09:08:40

@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

ikitommi10:08:37

@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.

onetom10:08:28

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...

onetom10:08:32

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

onetom10:08:57

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)}]]}))

ikitommi10:08:54

let’s continue on #reitit

onetom10:08:55

sorry, i thought i was on #reitit 🙂