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 )
2
2
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.
4
4
5
5
> This is a clj-commons maintained fork of the original [ ` hiredman/clj-http-lite ` ] ( https://github.com/hiredman/clj-http-lite ) repo.
6
6
@@ -43,28 +43,32 @@ The main HTTP client functionality is provided by the
43
43
```
44
44
45
45
The 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:
47
47
48
48
``` clojure
49
- (client/get " http ://google.com" )
49
+ (client/get " https ://google.com" )
50
50
=> {:status 200
51
- :headers {" date" " Sun, 01 Aug 2010 07:03:49 GMT"
51
+ :headers {" date" " Wed, 17 Aug 2022 21:37:58 GMT"
52
52
" cache-control" " private, max-age=0"
53
53
" content-type" " text/html; charset=ISO-8859-1"
54
54
...}
55
55
:body " <!doctype html>..." }
56
56
```
57
57
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.
59
59
60
60
``` clojure
61
- (client/get " http ://site.com/resources/id " )
61
+ (client/get " https ://httpbin.org/user-agent " )
62
62
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 })
64
65
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" ]
68
72
:body " {\" json\" : \" input\" }"
69
73
:headers {" X-Api-Version" " 2" }
70
74
:content-type :json
@@ -73,35 +77,41 @@ More example requests:
73
77
:accept :json })
74
78
75
79
; ; 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" )
77
84
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 })
80
88
81
89
; ; 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" }})
83
91
84
92
; ; 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:[email protected] /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" })
87
96
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" }})
90
99
```
91
100
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.
94
102
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
+ ```
97
108
98
109
### Nested params
99
110
100
111
Nested 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:
102
112
103
113
``` clojure
104
- (-> (client/get " https://httpbin.org/get"
114
+ (-> (client/get " https://httpbin.org/get"
105
115
{:query-params {:one {:two 2 :three 3 }}})
106
116
:body
107
117
println)
@@ -130,50 +140,54 @@ We'll use `httpbin.org` to demonstrate:
130
140
}
131
141
```
132
142
133
- ### Input coercion
143
+ ### Request body coercion
134
144
135
145
``` 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" )}) )
155
167
```
156
168
157
- ### Output coercion
169
+ ### Output body coercion
158
170
159
171
``` 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 " )
162
174
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 })
165
177
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 " })
168
180
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 })
172
184
173
185
; ; Return the body as a stream
174
- (client/get " http://site.com/bigrequest.html" {:as :stream })
175
186
; ; Note that the connection to the server will NOT be closed until the
176
187
; ; 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)))
177
191
```
178
192
179
193
A more general ` request ` function is also available, which is useful
@@ -182,34 +196,36 @@ as a primitive for building higher-level interfaces:
182
196
``` clojure
183
197
(defn api-action [method path & [opts]]
184
198
(client/request
185
- (merge {:method method :url (str " http ://site.com /" path)} opts)))
199
+ (merge {:method method :url (str " https ://some.api /" path)} opts)))
186
200
```
187
201
188
202
### Exceptions
189
203
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 ` .
192
206
193
207
``` 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)
201
216
```
202
217
203
- You can also ignore exceptions and handle them yourself:
218
+ You can suppress HTTP status exceptions and handle them yourself:
204
219
205
220
``` clojure
206
- (client/get " http ://site.com/broken " {:throw-exceptions false })
221
+ (client/get " https ://httpbin.org/404 " {:throw-exceptions false })
207
222
```
208
223
209
224
Or ignore an unknown host (methods return 'nil' if this is set to true and the host does not exist:
210
225
211
226
``` clojure
212
227
(client/get " http://aoeuntahuf89o.com" {:ignore-unknown-host? true })
228
+ ; ; => nil
213
229
```
214
230
215
231
### Proxies
@@ -238,8 +254,8 @@ such), check out the
238
254
239
255
## Design
240
256
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
243
259
server applications.
244
260
245
261
The 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.
255
271
256
272
To run tests for the JVM:
257
273
258
- $ bb clean
259
- $ bb deps
274
+ ``` shell
275
+ $ bb clean
276
+ $ bb deps
260
277
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
263
280
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
+ ```
266
284
267
285
### Babashka Tests
268
286
269
287
To run a small suite of sanity tests for babashka (found under ./bb] ):
270
288
271
- $ bb test:bb
289
+ ``` shell
290
+ $ bb test:bb
291
+ ```
272
292
273
293
### Linting
274
294
275
295
Our CI workflow lints sources with clj-kondo, and you can too!
276
296
277
- $ bb lint
297
+ ``` shell
298
+ $ bb lint
299
+ ```
278
300
279
301
### Release
280
302
0 commit comments