1- # ` clj-http-lite ` [ ![ cljdoc badge] ( https://cljdoc.xyz /badge/org.clj-commons/clj-http-lite )] ( https://cljdoc.xyz /d/org.clj-commons/clj-http-lite/CURRENT ) [ ![ CI] ( https://github.com/martinklepsch /clj-http-lite/workflows/Tests/badge.svg )] ( https://github.com/martinklepsch /clj-http-lite/actions ) [ ![ bb compatible] ( https://raw.githubusercontent.com/babashka/babashka/master/logo/badge.svg )] ( https://babashka.org )
1+ # ` clj-http-lite ` [ ![ cljdoc badge] ( https://cljdoc.org /badge/org.clj-commons/clj-http-lite )] ( https://cljdoc.org /d/org.clj-commons/clj-http-lite ) [ ![ CI tests ] ( https://github.com/clj-commons /clj-http-lite/workflows/Tests/badge.svg )] ( https://github.com/clj-commons /clj-http-lite/actions ) [ ![ Clojars ] ( https://img.shields.io/clojars/v/org.clj-commons/clj-http-lite.svg )] ( https://clojars.org/org.clj-commons/clj-http-lite ) [ ![ bb compatible] ( https://raw.githubusercontent.com/babashka/babashka/master/logo/badge.svg )] ( https://babashka.org )
22
3- A Clojure HTTP library similar to [ clj-http] ( http://github.com/dakrone/clj-http ) , but more lightweight. Compatible with GraalVM.
3+ A Clojure HTTP library similar to [ clj-http] ( http://github.com/dakrone/clj-http ) , but more lightweight. Compatible with Babashka and GraalVM.
44
55> This is a clj-commons maintained fork of the original [ ` hiredman/clj-http-lite ` ] ( https://github.com/hiredman/clj-http-lite ) repo.
66
@@ -43,28 +43,32 @@ The main HTTP client functionality is provided by the
4343```
4444
4545The client supports simple ` get ` , ` head ` , ` put ` , ` post ` , and ` delete `
46- requests. Responses are returned as Ring-style response maps:
46+ requests. They all return Ring-style response maps:
4747
4848``` clojure
49- (client/get " http ://google.com" )
49+ (client/get " https ://google.com" )
5050=> {:status 200
51- :headers {" date" " Sun, 01 Aug 2010 07:03:49 GMT"
51+ :headers {" date" " Wed, 17 Aug 2022 21:37:58 GMT"
5252 " cache-control" " private, max-age=0"
5353 " content-type" " text/html; charset=ISO-8859-1"
5454 ...}
5555 :body " <!doctype html>..." }
5656```
5757
58- More example requests:
58+ ** TIP ** : We encourage you to try out these examples in your REPL, ` httpbin.org ` is a free HTTP test playground and used in many examples.
5959
6060``` clojure
61- (client/get " http ://site.com/resources/id " )
61+ (client/get " https ://httpbin.org/user-agent " )
6262
63- (client/get " http://site.com/resources/3" {:accept :json })
63+ ; ; Tell the server you'd like a json response
64+ (client/get " https://httpbin.org/user-agent" {:accept :json })
6465
65- ; ; Various options:
66- (client/post " http://site.com/api"
67- {:basic-auth [" user" " pass" ]
66+ ; ; Or maybe you'd like html back
67+ (client/get " https://httpbin.org/html" {:accept " text/html" })
68+
69+ ; ; Various options
70+ (client/post " https://httpbin.org/anything"
71+ {:basic-auth [" joe" " cool" ]
6872 :body " {\" json\" : \" input\" }"
6973 :headers {" X-Api-Version" " 2" }
7074 :content-type :json
@@ -73,35 +77,41 @@ More example requests:
7377 :accept :json })
7478
7579; ; Need to contact a server with an untrusted SSL cert?
76- (client/get " https://alioth.debian.org" {:insecure? true })
80+ (client/get " https://expired.badssl.com" {:insecure? true })
81+
82+ ; ; By default we automatically follow 30* redirects...
83+ (client/get " https://httpbin.org/redirect-to?url=https%3A%2F%2Fclojure.org" )
7784
78- ; ; If you don't want to follow-redirects automatically:
79- (client/get " http://site.come/redirects-somewhere" {:follow-redirects false })
85+ ; ; ... but you don't have to
86+ (client/get " https://httpbin.org/redirect-to?url=https%3A%2F%2Fclojure.org"
87+ {:follow-redirects false })
8088
8189; ; Send form params as a urlencoded body
82- (client/post " http//site.com " {:form-params {:foo " bar" }})
90+ (client/post " https://httpbin.org/post " {:form-params {:foo " bar" }})
8391
8492; ; Basic authentication
85- (client/get " http://site.com/protected" {:basic-auth [" user" " pass" ]})
86- (client/get " http://site.com/protected" {:basic-auth " user:pass" })
93+ (client/get " https://joe:cool@httpbin.org/basic-auth/joe/cool" )
94+ (client/get " https://httpbin.org/basic-auth/joe/cool" {:basic-auth [" joe" " cool" ]})
95+ (client/get " https://httpbin.org/basic-auth/joe/cool" {:basic-auth " joe:cool" })
8796
88- ; ; Query parameters
89- (client/get " http ://site.com/search " {:query-params {" q" " foo, bar" }})
97+ ; ; Query parameters can be specified as a map
98+ (client/get " https ://httpbin.org/get " {:query-params {" q" " foo, bar" }})
9099```
91100
92- The client will also follow redirects on the appropriate ` 30* ` status
93- codes.
101+ The client transparently accepts and decompresses the ` gzip ` and ` deflate ` content encodings.
94102
95- The client transparently accepts and decompresses the ` gzip ` and
96- ` deflate ` content encodings.
103+ ``` Clojure
104+ (client/get " https://httpbin.org/gzip" )
105+
106+ (client/get " https://httpbin.org/deflate" )
107+ ```
97108
98109### Nested params
99110
100111Nested parameter ` {:a {:b 1}} ` in ` :form-params ` or ` :query-params ` is automatically flattened to ` a[b]=1 ` .
101- We'll use ` httpbin.org ` to demonstrate:
102112
103113``` clojure
104- (-> (client/get " https://httpbin.org/get"
114+ (-> (client/get " https://httpbin.org/get"
105115 {:query-params {:one {:two 2 :three 3 }}})
106116 :body
107117 println)
@@ -130,50 +140,54 @@ We'll use `httpbin.org` to demonstrate:
130140}
131141```
132142
133- ### Input coercion
143+ ### Request body coercion
134144
135145``` clojure
136- ; ; body as a byte-array
137- (client/post " http://site.com/resources" {:body my-byte-array})
138-
139- ; ; body as a string
140- (client/post " http://site.com/resources" {:body " string" })
141-
142- ; ; :body-encoding is optional and defaults to "UTF-8"
143- (client/post " http://site.com/resources"
144- {:body " string" :body-encoding " UTF-8" })
145-
146- ; ; body as a file
147- (client/post " http://site.com/resources"
148- {:body (clojure.java.io/file " /tmp/foo" ) :body-encoding
149- " UTF-8" })
150-
151- ; ; :length is NOT optional for passing an InputStream in
152- (client/post " http://site.com/resources"
153- {:body (clojure.java.io/input-stream " /tmp/foo" )
154- :length 1000 })
146+ ; ; body as byte-array
147+ (client/post " https://httbin.org/post" {:body (.getBytes " testing123" )})
148+
149+ ; ; body from a string
150+ (client/post " https://httpbin.org/post" {:body " testing456" })
151+
152+ ; ; string :body-encoding is optional and defaults to "UTF-8"
153+ (client/post " https://httpbin.org/post"
154+ {:body " mystring" :body-encoding " UTF-8" })
155+
156+ ; ; body from a file
157+ (require '[clojure.java.io :as io])
158+ (spit " clj-http-lite-test.txt" " from a file" )
159+ (client/post " https://httpbin.org/post"
160+ {:body (io/file " clj-http-lite-test.txt" )
161+ :body-encoding " UTF-8" })
162+
163+ ; ; from a stream
164+ (with-open [is (io/input-stream " clj-http-lite-test.txt" )]
165+ (client/post " https://httpbin.org/post"
166+ {:body (io/input-stream " clj-http-lite-test.txt" )}) )
155167```
156168
157- ### Output coercion
169+ ### Output body coercion
158170
159171``` clojure
160- ; ; The default output is a string body
161- (client/get " http ://site.com/foo.txt " )
172+ ; ; The default response body is a string body
173+ (client/get " https ://clojure.org " )
162174
163- ; ; Coerce as a byte-array
164- (client/get " http://site.com/favicon.ico " {:as :byte-array })
175+ ; ; Coerce to a byte-array
176+ (client/get " http://clojure.org " {:as :byte-array })
165177
166- ; ; Coerce as something other than UTF-8 string
167- (client/get " http://site.com/string.txt " {:as " UTF-16 " })
178+ ; ; Coerce to a string with using a specific charset, default is UTF-8
179+ (client/get " http://clojure.org " {:as " US-ASCII " })
168180
169- ; ; Try to automatically coerce the output based on the content-type
170- ; ; header (this is currently a BETA feature!)
171- (client/get " http ://site .com/foo.bar " {:as :auto })
181+ ; ; Try to automatically coerce the body based on the content-type
182+ ; ; response header charset
183+ (client/get " https ://google .com" {:as :auto })
172184
173185; ; Return the body as a stream
174- (client/get " http://site.com/bigrequest.html" {:as :stream })
175186; ; Note that the connection to the server will NOT be closed until the
176187; ; stream has been read
188+ (let [res (client/get " https://clojure.org" {:as :stream })]
189+ (with-open [body-stream (:body res)]
190+ (slurp body-stream)))
177191```
178192
179193A more general ` request ` function is also available, which is useful
@@ -182,34 +196,36 @@ as a primitive for building higher-level interfaces:
182196``` clojure
183197(defn api-action [method path & [opts]]
184198 (client/request
185- (merge {:method method :url (str " http ://site.com /" path)} opts)))
199+ (merge {:method method :url (str " https ://some.api /" path)} opts)))
186200```
187201
188202### Exceptions
189203
190- The client will throw exceptions on, well, exceptional status
191- codes. clj -http will throw an ` ex-info ` with the response as ` ex-data ` .
204+ The client will throw exceptions on, exceptional HTTP status
205+ codes. Clj -http-lite throws an ` ex-info ` with the response as ` ex-data ` .
192206
193207``` clojure
194- user=> (client/get " http://site.com/broken" )
195- Execution error (ExceptionInfo ) at clj-http.lite.client/wrap-exceptions$fn (client.clj:38 ).
196- clj-http: status 404
197- user=> (-> *e ex-data :status )
198- 404
199- user=> (-> *e ex-data keys)
200- (:headers :status :body )
208+ (client/get " https://httpbin.org/404" )
209+ ; ; => ExceptionInfo clj-http: status 404 clojure.core/ex-info (core.clj:4617)
210+
211+ (-> *e ex-data :status )
212+ ; ; => 404
213+
214+ (-> *e ex-data keys)
215+ ; ; => (:headers :status :body)
201216```
202217
203- You can also ignore exceptions and handle them yourself:
218+ You can suppress HTTP status exceptions and handle them yourself:
204219
205220``` clojure
206- (client/get " http ://site.com/broken " {:throw-exceptions false })
221+ (client/get " https ://httpbin.org/404 " {:throw-exceptions false })
207222```
208223
209224Or ignore an unknown host (methods return 'nil' if this is set to true and the host does not exist:
210225
211226``` clojure
212227(client/get " http://aoeuntahuf89o.com" {:ignore-unknown-host? true })
228+ ; ; => nil
213229```
214230
215231### Proxies
@@ -238,8 +254,8 @@ such), check out the
238254
239255## Design
240256
241- The design of ` clj-http ` is inspired by the
242- [ Ring] ( http ://github.com/mmcgrana /ring) protocol for Clojure HTTP
257+ The design of ` clj-http ` (and therefore ` clj-http-lite ` ) is inspired by the
258+ [ Ring] ( https ://github.com/ring-clojure /ring) protocol for Clojure HTTP
243259server applications.
244260
245261The client in ` clj-http.lite.core ` makes HTTP requests according to a given
@@ -255,26 +271,32 @@ are sugar over this `clj-http.lite.client/request` function.
255271
256272To run tests for the JVM:
257273
258- $ bb clean
259- $ bb deps
274+ ``` shell
275+ $ bb clean
276+ $ bb deps
260277
261- Run all Clojure tests against minimum supported version of Clojure (1.8)
262- $ clojure -M:test
278+ Run all Clojure tests against minimum supported version of Clojure (1.8)
279+ $ clojure -M:test
263280
264- Run Clojure against a specific Clojure version, for example 1.11
265- $ clojure -M:1.11:test
281+ Run Clojure against a specific Clojure version, for example 1.11
282+ $ clojure -M:1.11:test
283+ ```
266284
267285### Babashka Tests
268286
269287To run a small suite of sanity tests for babashka (found under ./bb] ):
270288
271- $ bb test:bb
289+ ``` shell
290+ $ bb test:bb
291+ ```
272292
273293### Linting
274294
275295Our CI workflow lints sources with clj-kondo, and you can too!
276296
277- $ bb lint
297+ ``` shell
298+ $ bb lint
299+ ```
278300
279301### Release
280302
0 commit comments