babashka-sci-dev

lispyclouds 2023-01-08T08:16:21.420469Z

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.

lispyclouds 2023-01-08T08:18:59.334459Z

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

lispyclouds 2023-01-08T08:22:06.373719Z

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

borkdude 2023-01-08T08:34:17.131849Z

@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

lispyclouds 2023-01-08T08:35:56.930579Z

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

lispyclouds 2023-01-08T08:38:24.692019Z

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

borkdude 2023-01-08T08:39:40.431149Z

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

lispyclouds 2023-01-08T08:40:30.499919Z

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

borkdude 2023-01-08T08:41:03.018419Z

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

borkdude 2023-01-08T08:42:27.955209Z

in general :as refers to the response

lispyclouds 2023-01-08T08:43:00.260059Z

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

borkdude 2023-01-08T08:43:28.909149Z

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

lispyclouds 2023-01-08T08:43:33.574659Z

yes

borkdude 2023-01-08T08:43:54.155449Z

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

borkdude 2023-01-08T08:44:42.971819Z

:content-type :json

borkdude 2023-01-08T08:45:07.720929Z

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

lispyclouds 2023-01-08T08:45:19.975829Z

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

lispyclouds 2023-01-08T08:45:49.905839Z

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

borkdude 2023-01-08T08:46:35.164499Z

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

lispyclouds 2023-01-08T08:47:05.832829Z

yeah good point

borkdude 2023-01-08T08:47:15.451589Z

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

lispyclouds 2023-01-08T08:47:23.594079Z

on it, thanks!

lispyclouds 2023-01-08T08:51:49.000599Z

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

lispyclouds 2023-01-08T08:53:30.369339Z

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

lispyclouds 2023-01-08T08:57:46.885439Z

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

lispyclouds 2023-01-08T09:02:05.885719Z

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

borkdude 2023-01-08T10:21:46.533129Z

@rahul080327 agreed :) I made a #babashka-http-client channel now