Skip to content

Commit 9d73e5d

Browse files
authored
docs: review and update docstrings (#41)
This exercise helped me to understand the API more deeply, hopefully it will help our users too. The biggest challenge was documenting `clj-http.lite.client/request`. Its previous docstring was way too vague for me to understand, as a user, what is available. Also challenging is the lack of definition of the supported API. I'm guessing our documented API is currently including lots of unnecessary internals. I reviewed all existing docstrings and updated where I thought I could be clearer and/or more consistent. I added no new docstrings. Also: added cljdoc.edn to explicitly list our docs. Closes #36
1 parent 4a01538 commit 9d73e5d

File tree

5 files changed

+104
-50
lines changed

5 files changed

+104
-50
lines changed

doc/cljdoc.edn

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{:cljdoc.doc/tree
2+
[["Readme" {:file "README.md"}]
3+
["Changelog" {:file "CHANGELOG.md"}]]}

src/clj_http/lite/client.clj

+80-28
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
(ns clj-http.lite.client
2-
"Batteries-included HTTP client."
2+
"Batteries-included HTTP client.
3+
4+
Among the many functions here you'll likely be most interested in
5+
[[get]] [[head]] [[put]] [[post]] [[delete]] or the slightly lower level [[request]]."
36
(:require [clj-http.lite.core :as core]
47
[clj-http.lite.links :refer [wrap-links]]
58
[clj-http.lite.util :as util]
@@ -233,8 +236,7 @@
233236
(client req))))
234237

235238
(defn wrap-request
236-
"Returns a battaries-included HTTP request function coresponding to the given
237-
core client. See client/client."
239+
"Returns a batteries-included HTTP request function."
238240
[request]
239241
;; note to the uninitiated: wrapper behaviour is applied to requests in order listed here but
240242
;; from last to first
@@ -257,51 +259,101 @@
257259
wrap-links
258260
wrap-unknown-host))
259261

260-
(def #^{:doc
261-
"Executes the HTTP request corresponding to the given map and returns
262-
the response map for corresponding to the resulting HTTP response.
263-
264-
In addition to the standard Ring request keys, the following keys are also
265-
recognized:
266-
* :url
267-
* :method
268-
* :query-params
269-
* :basic-auth
270-
* :content-type
271-
* :accept
272-
* :accept-encoding
273-
* :as
274-
275-
The following additional behaviors over also automatically enabled:
276-
* Exceptions are thrown for status codes other than 200-207, 300-303, or 307
277-
* Gzip and deflate responses are accepted and decompressed
278-
* Input and output bodies are coerced as required and indicated by the :as
279-
option."}
262+
(def ^{:arglists '([req])}
280263
request
264+
"Returns response map for executed HTTP `req` map.
265+
266+
Notice that some `req` key entries will be overwritten by automatic conversion to other key entries:
267+
268+
Request method
269+
* `:method` - ex. `:get`,`:head`,`:post`,`:put`,`:delete`, converts to `:request-method` with same value
270+
271+
Request URL
272+
* `:url` - ex. `\"https://joe:blow@example.com:443/some/path?q=clojure\"`, converts to:
273+
* `:scheme` - protocol `:https`
274+
* `:server-name` - host `\"example.com\"`
275+
* `:server-port` - `443` (if not specified, will be inferred from `:scheme`)
276+
* `:uri` - path `\"/some/path\"`
277+
* `:user-info` - `\"joe:blow\"`, converts to:
278+
* `:basic-auth` - which automatically converts to appropriate `:headers`
279+
* `:query-string` - `\"q=clojure\"`
280+
* `:query-params` - ex. `{\"q\" \"clojure\"}` or `{:q \"clojure\"}` converts to `:query-string` (see above)
281+
282+
Request body & headers
283+
* `:body` - can be a string, byte array, File or input stream
284+
* `:body-encoding` - charset ex. `\"UTF-16\"`, defaults to `\"UTF-8\"`, iff `:body` is string converts to:
285+
* `:body` encoded in charset
286+
* `:character-encoding` set to charset which converts to appropriate `:headers` iff `:content-type` also set
287+
* `:content-type` - media type of request body, converts to appropriate `:headers` entry, specify:
288+
* keyword as shorthand, ex. `:json` for `\"application/json\"`
289+
* string for verboten, ex. `\"text/html\"`
290+
* `:form-params` - ex. `{\"q\" \"clojure\"}` or `{:q \"clojure\"}`, iff `:method` is `:post`: converts to:
291+
* urlencoded `:body`
292+
* appropriate `:headers` entry
293+
* `:oauth-token` - bearer authorization token, ex. `\"my70k3nh3r3\"`, converts to appropriate `:headers` entry
294+
* `:basic-auth` - basic authentication, converts to appropriate `:headers` entry, (see also `:url` and `:user-info`), specify:
295+
* vector `[\"uname\" \"pass\"]` becomes `\"uname:pass\"`
296+
* use string for verboten
297+
* `:accept-encoding` - vector of accepted response encodings, ex. `[:gzip :deflate :identity]`, converts to appropriate `:headers` entry
298+
* `:accept` - accept response of media type, converts to appropriate `:headers` entry, specify
299+
* keyword as shorthand, ex. `:json` for `\"application/json\"`
300+
* string for verboten, ex. `\"text/html\"`
301+
* `:headers` - explicitly set request headers, ex. `{\"Cache-Control\" \"no-cache\"}`
302+
303+
Request behaviour
304+
* `:as` - specifies how response body should be coerced:
305+
* `:stream`
306+
* `:byte-array`
307+
* `:auto` - to string decoded with `charset` in response `:headers` `content-type` `charset` else UTF-8
308+
* `\"charset\"` - to string decoded with `charset` ex. `\"utf-16\"`
309+
* else - to string decoded with UTF-8
310+
* `:follow-redirects` - specify `false` to not follow response redirects
311+
* `:throw-exceptions` - specify `false` to not throw on https status error codes
312+
* `:ignore-unknown-host?` - specify `true` to not throw on unknown host
313+
* `:insecure?` - allow connection with an invalid SSL certificate
314+
* `:conn-timeout` - number of milliseconds to wait to establish a connection
315+
* `:socket-timeout` - number of milliseconds to wait for data to be available to read
316+
* `:save-request?` - specify `true` to include ultimate converted `:request` used in response map
317+
* `:chunk-size` - in bytes, enables streaming of HTTP request body with chunk-size bytes,
318+
see [JDK docs](https://docs.oracle.com/javase/8/docs/api/java/net/HttpURLConnection.html#setChunkedStreamingMode-int-)
319+
for details
320+
321+
Response map keys:
322+
* `:status` - http status code, see `:throw-exceptions` above
323+
* `:headers` - response headers
324+
* `:body` - response body, gzip and deflate responses are accepted and decompressed. See `:as` above.
325+
* `:request` - see `:save-request?` above
326+
327+
See [README](/README.md#usage) for example usages."
281328
(wrap-request #'core/request))
282329

283330
(defn get
284-
"Like #'request, but sets the :method and :url as appropriate."
331+
"Executes HTTP GET request for `url` and, optionally, more `req` attributes.
332+
See [[request]]."
285333
[url & [req]]
286334
(request (merge req {:method :get :url url})))
287335

288336
(defn head
289-
"Like #'request, but sets the :method and :url as appropriate."
337+
"Executes HTTP HEAD request for `url` and, optionally, more `req` attributes.
338+
See [[request]]."
290339
[url & [req]]
291340
(request (merge req {:method :head :url url})))
292341

293342
(defn post
294-
"Like #'request, but sets the :method and :url as appropriate."
343+
"Executes HTTP POST request for `url` and, optionally, more `req` attributes.
344+
See [[request]]."
295345
[url & [req]]
296346
(request (merge req {:method :post :url url})))
297347

298348
(defn put
299-
"Like #'request, but sets the :method and :url as appropriate."
349+
"Executes HTTP PUT request for `url` and, optionally, more `req` attributes.
350+
See [[request]]."
300351
[url & [req]]
301352
(request (merge req {:method :put :url url})))
302353

303354
(defn delete
304-
"Like #'request, but sets the :method and :url as appropriate."
355+
"Executes HTTP DELETE request for `url` and, optionally, more `req` attributes.
356+
See [[request]]."
305357
[url & [req]]
306358
(request (merge req {:method :delete :url url})))
307359

src/clj_http/lite/core.clj

+6-9
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@
77
(set! *warn-on-reflection* true)
88

99
(defn parse-headers
10-
"Takes a URLConnection and returns a map of names to values.
10+
"Returns a map of names to values for URLConnection `conn`.
1111
12-
If a name appears more than once (like `set-cookie`) then the value
12+
If a header name appears more than once (like `set-cookie`) then the value
1313
will be a vector containing the values in the order they appeared
1414
in the headers."
1515
[conn]
@@ -26,8 +26,8 @@
2626
(vec v))))))))
2727

2828
(defn- coerce-body-entity
29-
"Coerce the http-entity from an HttpResponse to either a byte-array, or a
30-
stream that closes itself and the connection manager when closed."
29+
"Return body response from HttpURLConnection `conn` coerced to either a byte-array,
30+
or a stream."
3131
[{:keys [as]} conn]
3232
(let [ins (try
3333
(.getInputStream ^HttpURLConnection conn)
@@ -74,11 +74,8 @@
7474
(def-insecure)
7575

7676
(defn request
77-
"Executes the HTTP request corresponding to the given Ring request map and
78-
returns the Ring response map corresponding to the resulting HTTP response.
79-
80-
Note that where Ring uses InputStreams for the request and response bodies,
81-
the clj-http uses ByteArrays for the bodies."
77+
"Executes the HTTP request corresponding to the given Ring `req` map and
78+
returns the Ring response map corresponding to the resulting HTTP response."
8279
[{:keys [request-method scheme server-name server-port uri query-string
8380
headers content-type character-encoding body socket-timeout
8481
conn-timeout insecure? save-request? follow-redirects

src/clj_http/lite/links.clj

+4-2
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,10 @@
5454
response))
5555

5656
(defn wrap-links
57-
"Add a :links key to the response map that contains parsed Link headers. The
58-
links will be represented as a map, with the 'rel' value being the key. The
57+
"Returns request wrapper fn for `client` that adds
58+
a `:links` key to the response map that contains parsed link headers.
59+
60+
The links are returned as a map, with the 'rel' value being the key. The
5961
URI is placed under the 'href' key, to mimic the HTML link element.
6062
6163
e.g. Link: <http://example.com/page2.html>; rel=next; title=\"Page 2\"

src/clj_http/lite/util.clj

+11-11
Original file line numberDiff line numberDiff line change
@@ -9,29 +9,29 @@
99
(set! *warn-on-reflection* true)
1010

1111
(defn utf8-bytes
12-
"Returns the UTF-8 bytes corresponding to the given string."
12+
"Returns the UTF-8 bytes for string `s`."
1313
[#^String s]
1414
(.getBytes s "UTF-8"))
1515

1616
(defn utf8-string
17-
"Returns the String corresponding to the UTF-8 decoding of the given bytes."
17+
"Returns the string for UTF-8 decoding of bytes `b`."
1818
[#^"[B" b]
1919
(String. b "UTF-8"))
2020

2121
(defn url-decode
22-
"Returns the form-url-decoded version of the given string, using either a
23-
specified encoding or UTF-8 by default."
22+
"Returns the form-url-decoded version of `encoded` string, using either a
23+
specified `encoding` or UTF-8 by default."
2424
[^String encoded & [encoding]]
2525
(let [^String encoding (or encoding "UTF-8")]
2626
(URLDecoder/decode encoded encoding)))
2727

2828
(defn url-encode
29-
"Returns an UTF-8 URL encoded version of the given string."
29+
"Returns an UTF-8 URL encoded version of `unencoded` string."
3030
[^String unencoded]
3131
(URLEncoder/encode unencoded "UTF-8"))
3232

3333
(defmacro base64-encode
34-
"Encode an array of bytes into a base64 encoded string."
34+
"Encode an array of `unencoded` bytes into a base64 encoded string."
3535
[unencoded]
3636
(if (try (import 'javax.xml.bind.DatatypeConverter)
3737
(catch Exception _))
@@ -41,7 +41,7 @@
4141
`(.encodeToString (java.util.Base64/getEncoder) ~unencoded))))
4242

4343
(defn to-byte-array
44-
"Returns a byte array for the InputStream provided."
44+
"Returns a byte array for InputStream `is`."
4545
[is]
4646
(let [chunk-size 8192
4747
baos (ByteArrayOutputStream.)
@@ -54,15 +54,15 @@
5454

5555

5656
(defn gunzip
57-
"Returns a gunzip'd version of the given byte array."
57+
"Returns a gunzip'd version of byte array `b`."
5858
[b]
5959
(when b
6060
(if (instance? InputStream b)
6161
(GZIPInputStream. b)
6262
(to-byte-array (GZIPInputStream. (ByteArrayInputStream. b))))))
6363

6464
(defn gzip
65-
"Returns a gzip'd version of the given byte array."
65+
"Returns a gzip'd version byte array `b`."
6666
[b]
6767
(when b
6868
(let [baos (ByteArrayOutputStream.)
@@ -72,13 +72,13 @@
7272
(.toByteArray baos))))
7373

7474
(defn inflate
75-
"Returns a zlib inflate'd version of the given byte array."
75+
"Returns a zlib inflate'd version byte array `b`."
7676
[b]
7777
(when b
7878
(to-byte-array (InflaterInputStream. (ByteArrayInputStream. b)))))
7979

8080
(defn deflate
81-
"Returns a deflate'd version of the given byte array."
81+
"Returns a deflate'd version byte array `b`."
8282
[b]
8383
(when b
8484
(to-byte-array (DeflaterInputStream. (ByteArrayInputStream. b)))))

0 commit comments

Comments
 (0)