Today clj-http is the de-facto standard HTTP client for Clojure. It is an excellent library, but it is also a large dependency since it is based on Apache HTTP. It also doesn't support HTTP/2 (yet).
Enter java-http-clj. It is inspired by both clj-http and Ring and built on java.net.http
that ships with with Java 11. As such it comes with no extra dependencies if you're already using Java 11, and it fully supports HTTP/2 out of the box.
java-http-clj requires Clojure 1.9+ and Java 11+.
First, require the library:
(:require [java-http-clj.core :as http])
The most common HTTP methods (GET, POST, PUT, HEAD, DELETE) have a function of the same name. This function takes three arguments (where the last two are optional): a URL, a request and an options map (refer to send docs for details).
;; If you don't specify any options defaults are provided
(http/get "http://www.google.com")
;; With request options
(http/get "http://www.google.com" {:headers {"Accept" "application/json"
"Accept-Encoding" ["gzip" "deflate"]}
:timeout 2000})
(http/post "http://www.google.com" {:body "{\"foo\":\"bar\"}"})
;; The request body can be a string, an input stream or a byte array...
(http/post "http://www.google.com" {:body (.getBytes "{\"foo\":\"bar\"}")})
;; ...and you can choose the response body format with the `:as` option
(http/post "http://www.google.com" {:body "{\"foo\":\"bar\"}"} {:as :byte-array})
To make an async request, use the send-async
function (currently there is no sugar for async requests):
;; Returns a java.util.concurrent.CompletableFuture
(http/send-async {:uri "http://www.google.com" :method :get})
;; Takes an optional callback and exception handler
(http/send-async {:uri "http://www.google.com" :method :get})
(fn [r] (do-something-with-response r))
(fn [e] (println "oops, something blew up"))
All request functions take an opts
map for customization (refer to send docs for details).
;; Provide a custom client
(def client (build-client {:follow-redirects :always}))
(http/send {:uri "http://www.google.com" :method :get} {:client client})
;; Skip map conversion and return the java.net.http.HttpResponse object
user=> (http/send {:uri "http://www.google.com" :method :get} {:raw? true})
object[jdk.internal.net.http.HttpResponseImpl "0x88edd90" "(GET http://www.google.com) 200"]
java-http-clj also includes a WebSocket API. The WebSocket API in java.net.http is based around CompletableFuture and functional interfaces which interop poorly with Clojure. Hence, java-http-clj presents a simplified, synchronous API that covers the basic use-cases.
The API consists of three methods: build-websocket
, send
and close
. The Java API requires you to maintain a request counter for each invocation, but java-http-clj manages this for you automatically.
;; Create a websocket
(def ws
(build-websocket
"ws://localhost:8080/ws"
{:on-text (fn [ws string last?]
(println "Received some text!" string))
:on-binary (fn [ws byte-array last?]
(println "Got some bytes!" (vec byte-array)))
:on-error (fn [ws throwable]
(println "Uh oh!" (.getMessage throwable)))}))
;; Send some data (strings, ByteBuffers, byte arrays or something that can be coerced to a string)
and return the websocket
(-> ws
(send "abc")
(send (byte-array [1 2 3]))
(send 123))
;; Close the output of websocket when you are done
(close ws)
There is also build-websocket-async
and send-async
that return a CompletableFuture
. These functions are probably best used together with some asynchronous framework that allows you to compose CompletableFutures
(for example Manifold).
HttpResponse.BodySubscribers
are not available directly through Clojure, since Clojure has its own stream-processing facilities that are more idiomatic than the Java equivalents.:as
option but leaves it up to the user to parse the data as they see fitIf any of this is deal-breaker for you, I recommend clj-http which is a much more fully-featured HTTP client.
Bug fixes are always welcome, just open a PR! If you want to implement a new feature or make substantial changes to existing ones, please open an issue first and outline your ideas.
Copyright © 2018-2019 John Schmidt
Released under the MIT License: http://www.opensource.org/licenses/mit-license.php
Can you improve this documentation?Edit on GitHub
cljdoc is a website building & hosting documentation for Clojure/Script libraries
× close