Fork me on GitHub
#babashka-sci-dev
<
2023-01-08
>
lispyclouds08:01:21

would a default interceptor in http-client to make a request send json when a header Content-Type: application/json is present be useful? it would then treat the body as json: if a map or a vec is passed, it would json/generate-string on it. so that the user doesnt have to do it when making the body.

lispyclouds08:01:59

i sometimes forget the json/generate-string on the body and it fails the ->body-publisher cond

lispyclouds08:01:06

or maybe even a new opt :as :json which does both header adding and body coercion?

borkdude08:01:17

@rahul080327 You can make an :as :json interceptor like this: https://github.com/babashka/http-client#interceptors Perhaps it should be built-in, but you can do that in user space right now

lispyclouds08:01:56

yeah just saw it after i sent it 😅 im fine with the usage now, if you think its useful as built-in, happy to PR

lispyclouds08:01:24

the example talks about accepting json, i was more on sending json as well. could that be built in as well?

borkdude08:01:40

well's, it's your interceptor right? so you can do whatever you want

lispyclouds08:01:30

yep, i meant would you consider it built in? i can use it totally fine as of now too with user code 🙂

borkdude08:01:03

the thing is, that you can only express so much with :as :json : request, response, body, keywordize-keys?

borkdude08:01:27

in general :as refers to the response

lispyclouds08:01:00

yeah hence i was thinking more on the presence of the content-type header

borkdude08:01:28

you mean, if the content-type is json, then encode it automatically?

borkdude08:01:54

what's next, if you forget to set the content type, :as :json should also do it?

borkdude08:01:42

:content-type :json

borkdude08:01:07

I'll keep it in the back of my mind, and it's worth looking at what clj-http and hato are doing here as well

lispyclouds08:01:19

so this is just for sending the request: if user sets the content-type to application/json, we check if the body can be json encoded, and then encode it

lispyclouds08:01:49

as for the response, yeah we do have a limitation of expression like you said

borkdude08:01:35

the thing is, I'd like to keep http-client dependency free and if you start doing things like this, you have to check what kind of json dependencies are available. it's not a problem per se, but I'd like to avoid it if possible

lispyclouds08:01:05

yeah good point

borkdude08:01:15

can you at least check what clj-http and hato are doing? I have to get going, I'll read when I come back

lispyclouds08:01:23

on it, thanks!

lispyclouds08:01:49

for clj-http:

;; Send form params as a json encoded body (POST or PUT)
(client/post "" {:form-params {:foo "bar"} :content-type :json})

;; Send form params as a json encoded body (POST or PUT) with options
(client/post "" {:form-params {:foo "bar"}
                                   :content-type :json
                                   :json-opts {:date-format "yyyy-MM-dd"}})

;; Send form params as a Transit encoded JSON body (POST or PUT) with options
(client/post "" {:form-params {:foo "bar"}
                                   :content-type :transit+json
                                   :transit-opts
                                   {:encode {:handlers {}}
                                    :decode {:handlers {}}}})

;; Send form params as a Transit encoded MessagePack body (POST or PUT) with options
(client/post "" {:form-params {:foo "bar"}
                                   :content-type :transit+msgpack
                                   :transit-opts
                                   {:encode {:handlers {}}
                                    :decode {:handlers {}}}})

lispyclouds08:01:30

Output coercion with :as :json, :as :json-string-keys or :as :x-www-form-urlencoded, will only work with an optional dependency

clj-http currently has four optional dependencies, cheshire, crouton, tools.reader and ring/ring-codec

lispyclouds08:01:46

Hato seems to only do output coercion:

Coerce response body with certain format: :json, :json-string-keys, :clojure, :transit+json, :transit+msgpack. JSON and transit coercion require optional dependencies cheshire (5.9.0 or later) and com.cognitect/transit-clj to be installed, respectively.

; Coerces transit. Requires optional dependency com.cognitect/transit-clj.
(hc/get "" {:as :transit+json})
(hc/get "" {:as :transit+msgpack})

; Coerces JSON strings into clojure data structure
; Requires optional dependency cheshire
(hc/get "" {:as :json})
(hc/get "" {:as :json-string-keys})

lispyclouds09:01:05

yeah the more i read it, i see the simplicity of not including json/something else dependency. would be fine to do it in user space. one fine day the jvm adds two things: unix sockets http and json handling. 🤞:skin-tone-5:

borkdude10:01:46

@rahul080327 agreed :) I made a #C04J0N76E2G channel now