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.
i sometimes forget the json/generate-string on the body and it fails the ->body-publisher cond
or maybe even a new opt :as :json which does both header adding and body coercion?
@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
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
the example talks about accepting json, i was more on sending json as well. could that be built in as well?
well's, it's your interceptor right? so you can do whatever you want
yep, i meant would you consider it built in? i can use it totally fine as of now too with user code 🙂
the thing is, that you can only express so much with :as :json : request, response, body, keywordize-keys?
in general :as refers to the response
yeah hence i was thinking more on the presence of the content-type header
you mean, if the content-type is json, then encode it automatically?
yes
what's next, if you forget to set the content type, :as :json should also do it?
:content-type :json
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
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
as for the response, yeah we do have a limitation of expression like you said
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
yeah good point
can you at least check what clj-http and hato are doing? I have to get going, I'll read when I come back
on it, thanks!
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 {}}}}) 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-codecHato 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}) 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. 🤞🏾
@rahul080327 agreed :) I made a #babashka-http-client channel now