Skip to content

Commit c4a2278

Browse files
author
Dr. Christian Betz
committed
Fixed readme, got rid of unneccessary code, allow keyword headers
README now reflects our changes. EDN is now accepted through muuntaja, and you can use keywords as header names, e.g. `:headers {:user-agent "hato"}`.
1 parent 4748ce9 commit c4a2278

File tree

4 files changed

+52
-44
lines changed

4 files changed

+52
-44
lines changed

README.md

Lines changed: 50 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,17 @@
11
# hato
22

3-
<!--
4-
[![Clojars Project](https://img.shields.io/clojars/v/hato.svg)](https://clojars.org/hato)
5-
6-
[![CircleCI](https://circleci.com/gh/gnarroway/hato.svg?style=svg)](https://circleci.com/gh/gnarroway/hato)
7-
-->
3+
[![Clojars Project](https://img.shields.io/clojars/v/gorillalabs/hato.svg)](https://clojars.org/gorillalabs/hato)
4+
[![Build Status](https://travis-ci.org/gorillalabs/hato.svg)](https://travis-ci.org/gorillalabs/hato)
5+
[![Dependencies Status](https://versions.deps.co/gorillalabs/hato/status.svg)](https://versions.deps.co/gorillalabs/hato)
6+
[![Downloads](https://versions.deps.co/gorillalabs/hato/downloads.svg)](https://versions.deps.co/gorillalabs/hato)
7+
[![cljdoc badge](https://cljdoc.xyz/badge/gorillalabs/hato)](https://cljdoc.xyz/jump/release/gorillalabs/hato)
88

99
An HTTP client for Clojure.
1010

11-
Hato is wrapping JDK 11's [HttpClient](https://openjdk.java.net/groups/net/httpclient/intro.html).
12-
1311
It supports both HTTP/1.1 and HTTP/2, with synchronous and asynchronous execution modes as well as websockets.
1412

15-
In general, it will feel familiar to users of http clients like [clj-http](https://github.com/dakrone/clj-http).
13+
In general, it will feel familiar to users of http clients like [clj-http](https://github.com/dakrone/clj-http), while Hato is wrapping JDK 11's [HttpClient](https://openjdk.java.net/groups/net/httpclient/intro.html) instead of the [org.apache.httpcomponents](http://hc.apache.org), and not brining a server along also as [http-kit](https://github.com/http-kit/http-kit). This is a fork of [hato](https://github.com/gnarroway/hato).
14+
1615
The API is designed to be idiomatic and to make common tasks convenient, whilst
1716
still allowing the underlying HttpClient to be configured via native Java objects.
1817

@@ -23,12 +22,12 @@ Please try it out and raise any issues you may find.
2322

2423
## Installation
2524

26-
hato requires JDK 11 and above. If you are running an older version of Java, please look at [clj-http](https://github.com/dakrone/clj-http).
25+
hato requires JDK 11 and above. If you are running an older version of Java, please look at [clj-http](https://github.com/dakrone/clj-http) instead.
2726

2827
For Leiningen, add this to your project.clj
2928

3029
```clojure
31-
[hato "0.5.0"]
30+
[gorillalabs/hato "RELEASE"]
3231
```
3332

3433
## Quickstart
@@ -152,21 +151,15 @@ request and returns a response. Convenience wrappers are provided for the http v
152151
`as` Return response body in a certain format. Valid options:
153152

154153
- Return an object type: `:string` (default), `:byte-array`, `:stream`, `:discarding`,
155-
- Coerce response body with certain format: `:json`, `:json-string-keys`,
156-
`:json-strict`, `:json-strict-string-keys`, `:clojure`, `:transit+json`, `:transit+msgpack`. JSON and transit
157-
coercion require optional dependencies [cheshire](https://github.com/dakrone/cheshire) and
158-
[com.cognitect/transit-clj](https://github.com/cognitect/transit-clj) to be installed, respectively.
154+
- Coerce response body with certain format: `:edn`, `:json`, `:transit+json`, `:transit+msgpack` with the help of [gorillalabs/muuntaja](https://github.com/gorillalabs/muuntaja).
159155
- A [`java.net.http.HttpRequest$BodyHandler`](https://docs.oracle.com/en/java/javase/11/docs/api/java.net.http/java/net/http/HttpResponse.BodyHandler.html).
160156
Note that decompression is enabled by default but only handled for the options above. A custom BodyHandler
161157
may require opting out of compression, or implementing a multimethod specific to the handler.
162-
163-
`coerce` Determine which status codes to coerce response bodies. `:unexceptional` (default), `:always`, `:exceptional`.
164-
This presently only has an effect for json coercions.
165158

166159
`query-params` A map of options to turn into a query string. See usage examples for details.
167160

168161
`form-params` A map of options that will be sent as the body, depending on the `content-type` option. For example,
169-
set `:content-type :json` to coerce the form-params to a json string (requires [cheshire](https://github.com/dakrone/cheshire)).
162+
set `:content-type :json` to coerce the form-params to a json string (using [gorillalabs/muuntaja](https://github.com/gorillalabs/muuntaja)).
170163
See usage examples for details.
171164

172165
`multi-param-style` Decides how to represent array values when converting `query-params` into a query string. Accepts:
@@ -309,7 +302,7 @@ As a convenience, nesting can also be controlled by `:flatten-nested-keys`:
309302

310303
### Output coercion
311304

312-
hato performs output coercion of the response body, returning a string by default.
305+
You can control whether you like hato to return an `InputStream` (using `:as :stream`), `byte-array` (using `:as :byte-array`) or `String` (`:as String`) with no further coercion.
313306

314307
```clojure
315308
; Returns a string response
@@ -320,32 +313,51 @@ hato performs output coercion of the response body, returning a string by defaul
320313

321314
; Returns an InputStream
322315
(hc/get "http://moo.com" {:as :stream})
316+
```
323317

324-
; Coerces clojure strings
325-
(hc/get "http://moo.com" {:as :clojure})
318+
If you do not state an `:as` (or give it any other value), hato performs output coercion of the response body based upon the content type header. So, what you're looking for here is the accept header and a friendly web server listening to whatever you like best.
326319

327-
; Coerces transit. Requires optional dependency com.cognitect/transit-clj.
328-
(hc/get "http://moo.com" {:as :transit+json})
329-
(hc/get "http://moo.com" {:as :transit+msgpack})
320+
```clojure
321+
; Requests EDN, returns Clojure datastructure
322+
(hc/get "https://clojars.org/api/groups/gorillalabs" {:accept :edn})
323+
324+
; Coerces transit.
325+
(hc/get "https://clojars.org/api/groups/gorillalabs" {:accept :transit+json})
330326

331-
; Coerces JSON strings into clojure data structure
332-
; Requires optional dependency cheshire
333-
(hc/get "http://moo.com" {:as :json})
334-
(hc/get "http://moo.com" {:as :json-strict})
335-
(hc/get "http://moo.com" {:as :json-string-keys})
336-
(hc/get "http://moo.com" {:as :json-strict-string-keys})
327+
(hc/get "http://moo.com" {:accept :transit+msgpack})
337328

338-
; Coerce responses with exceptional status codes
339-
(hc/get "http://moo.com" {:as :json :coerce :always})
329+
; Coerces JSON into clojure data structure
330+
(hc/get "http://moo.com" {:accept :json})
340331
```
341332

342-
By default, hato only coerces JSON responses for unexceptional statuses. Control this with the `:coerce` option:
333+
Do add new content types or alter existing ones, you can pass a [muuntaja instance or muuntaja options](https://github.com/gorillalabs/muuntaja#configuration) using the `:muuntaja` key:
343334

344-
```clojure
345-
:unexceptional ; default - only coerce response bodies for unexceptional status codes
346-
:exceptional ; only coerce for exceptional status codes
347-
:always ; coerce for any status code
348335
```
336+
(require '[muuntaja.core :as m])
337+
338+
(hc/get "https://httpbin.org/get"
339+
{:accept :json
340+
:muuntaja (assoc-in m/default-options
341+
[:formats "application/json" :decoder 1 :decode-key-fn] false)})
342+
```
343+
344+
If you issue multiple requests, you might want to use a muuntaja instance instead:
345+
346+
```
347+
(require '[muuntaja.core :as m])
348+
349+
(def m
350+
"The `muuntaja.core/Muuntaja` instance we use to decode http responses."
351+
(m/create
352+
(assoc-in
353+
m/default-options
354+
[:formats "application/json" :decoder 1 :decode-key-fn] false)))
355+
356+
(hc/get "https://httpbin.org/get"
357+
{:accept :json
358+
:muuntaja m})
359+
```
360+
349361

350362
### Certificate authentication
351363

@@ -490,7 +502,7 @@ can be wrapped in e.g. [manifold](https://github.com/ztellman/manifold), to give
490502
`opts` Additional options may be a map of any of the following keys:
491503

492504
- `:http-client` An `HttpClient` (e.g. created by `hato.client/build-http-client`). If not provided, a default client will be used.
493-
- `:headers` Adds the given name-value pair to the list of additional HTTP headers sent during the opening handshake.
505+
- `:headers` Adds the given name-value pair to the list of additional HTTP headers sent during the opening handshake (feel free to use keywords).
494506
- `:connect-timeout` Sets a timeout for establishing a WebSocket connection, in milliseconds.
495507
- `:subprotocols` Sets a request for the given subprotocols.
496508
- `:listener` A WebSocket listener. If a `WebSocket$Listener` is provided, it will be used directly.

src/hato/client.clj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -296,7 +296,7 @@
296296
(.version builder (->Version version)))
297297

298298
(doseq [[header-n header-v] headers]
299-
(.header builder header-n header-v))
299+
(.header builder (name header-n) header-v))
300300

301301
(.build builder)))
302302

src/hato/middleware.clj

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -107,10 +107,6 @@
107107
;; Multimethods for coercing body type to the :as key
108108
(defmulti coerce-response-body (fn [muuntaja-instance req response] (:as req)))
109109

110-
(defmethod coerce-response-body :clojure [_ _ {:keys [body] :as resp}]
111-
(let [^String charset (or (-> resp :content-type-params :charset) "UTF-8")]
112-
(assoc resp :body (edn/read-string (String. ^"[B" body charset)))))
113-
114110
(defmethod coerce-response-body :byte-array [_ _ resp]
115111
resp)
116112

test/hato/middleware_test.clj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,7 @@
180180
(= {:a 1} (-> ((wrap-response-body-coercion (constantly {:status 200 :body (.getBytes "{\"a\": 1}")})) {:as :json}) :body)))
181181

182182
(testing "clojure coercions"
183-
(is (= {:a 1} (-> ((wrap-response-body-coercion (constantly {:status 200 :body (.getBytes "{:a 1}")})) {:as :clojure}) :body))))
183+
(is (= {:a 1} (-> ((wrap-muuntaja (wrap-response-body-coercion (wrap-content-type (constantly {:status 200 :headers {"Content-Type" "application/edn"} :body (.getBytes "{:a 1}") :muuntaja default-muuntaja-instance})))) {}) :body))))
184184

185185
(testing "transit coercions"
186186
(= {:a [1 2]} (-> ((wrap-response-body-coercion (wrap-content-type (constantly {:status 200 :body (.getBytes "[\"^ \",\"~:a\",[1,2]]") :headers {"content-type" "application/transit+json"}}))) {:as :transit+json}) :body)))

0 commit comments

Comments
 (0)