Skip to content

A zero dependency HTTP library built on java.net.http.HttpClient.

License

Notifications You must be signed in to change notification settings

owainlewis/java-http-clj

Repository files navigation

java-http-clj

Clojars Project License: MIT

A Clojure HTTP client library that wraps the Java 11+ HTTP client. This library provides a simple, idiomatic Clojure interface to the modern Java HTTP client while leveraging its powerful features.

Features

  • Simple, idiomatic Clojure API
  • Synchronous and asynchronous requests
  • Support for all HTTP methods (GET, POST, PUT, DELETE, etc.)
  • Customizable client configuration (timeouts, redirects, etc.)
  • Support for different response body types (string, bytes, stream)
  • Basic authentication support
  • Built on the modern Java 11+ HTTP client for performance and reliability

Requirements

  • Java 11 or higher
  • Clojure 1.10 or higher

Installation

Add the following dependency to your project.clj:

[com.owainlewis/java-http-clj "0.3.1-SNAPSHOT"]

Or with deps.edn:

{:deps {com.owainlewis/java-http-clj {:mvn/version "0.3.1-SNAPSHOT"}}}

Quick Start

(require '[java-http-clj.core :as http])

;; Simple GET request
(http/get "https://api.example.com/users")

;; POST request with JSON body
(http/post "https://api.example.com/users" 
           "{\"name\": \"John\", \"email\": \"john@example.com\"}" 
           {:headers {"Content-Type" "application/json"}})

;; Asynchronous request with callback
(http/async-request 
  {:method :get :url "https://api.example.com/users"} 
  {} 
  (fn [response] (println "Got response:" (:status response))))

Usage Examples

Basic Requests

(require '[java-http-clj.core :as http])

;; GET request
(http/get "https://api.example.com/users")

;; POST request with body
(http/post "https://api.example.com/users" "Hello, world!")

;; PUT request
(http/put "https://api.example.com/users/123" "{\"name\": \"Updated Name\"}")

;; DELETE request
(http/delete "https://api.example.com/users/123")

;; HEAD request
(http/head "https://api.example.com/users")

;; OPTIONS request
(http/options "https://api.example.com/users")

;; PATCH request
(http/patch "https://api.example.com/users/123" "{\"name\": \"Patched Name\"}")

Request with Headers

(http/get "https://api.example.com/users" 
          {:headers {"Authorization" "Bearer token123"
                     "Accept" "application/json"}})

Basic Authentication

(http/get "https://api.example.com/protected" 
          {:basic-auth ["username" "password"]})

;; Or with the request map
(http/request {:method :get
               :url "https://api.example.com/protected"
               :basic-auth ["username" "password"]})

Custom Timeout

;; Set request timeout (in milliseconds)
(http/get "https://api.example.com/slow-endpoint" 
          {:timeout 5000})

Response Body Handling

;; Get response as string (default)
(http/get "https://api.example.com/users" 
          {:as :string})

;; Get response as byte array
(http/get "https://api.example.com/image.jpg" 
          {:as :bytes})

;; Get response as input stream
(http/get "https://api.example.com/large-file" 
          {:as :stream})

;; Discard response body
(http/head "https://api.example.com/users" 
           {:as :discard})

Asynchronous Requests

;; With callback
(http/async-request 
  {:method :get :url "https://api.example.com/users"} 
  {} 
  (fn [response] 
    (println "Status:" (:status response))
    (println "Body:" (:body response))))

;; Without callback (returns CompletableFuture)
(def future-response 
  (http/async-request 
    {:method :get :url "https://api.example.com/users"}))

;; Later, get the result
(def response (.get future-response))

Custom Client Configuration

(require '[java-http-clj.client :as client])

;; Create a custom client
(def custom-client 
  (client/build-client 
    {:connect-timeout 5000
     :follow-redirects :always
     :version :http2}))

;; Use the custom client
(http/get "https://api.example.com/users" 
          {:client custom-client})

;; Convenience functions for common configurations
(def timeout-client (client/client-with-timeout 5000))
(def http2-client (client/client-with-version :http2))
(def redirect-client (client/client-with-redirect-policy :always))

API Documentation

Core Functions

request

(request req)
(request req opts)

Makes an HTTP request and returns the response.

Request map options:

  • :method - HTTP method (:get, :post, :put, :delete, etc.)
  • :url - URL string
  • :headers - Map of headers
  • :body - Request body (String, byte[], InputStream, or Path)
  • :basic-auth - Vector of [username password]
  • :timeout - Request timeout in milliseconds

Client options:

  • :client - HttpClient instance to use
  • :timeout - Connection timeout in milliseconds
  • :follow-redirects - Redirect policy (:always, :never, :normal)
  • :version - HTTP version (:http1.1, :http2)
  • :as - Response body type (:string, :bytes, :stream, :discard)

async-request

(async-request req)
(async-request req opts)
(async-request req opts callback)

Makes an asynchronous HTTP request. Returns a CompletableFuture that will complete with the response. If a callback function is provided, it will be called with the response.

HTTP Method Helpers

(get url)
(get url opts)

(post url body)
(post url body opts)

(put url body)
(put url body opts)

(delete url)
(delete url opts)

(head url)
(head url opts)

(options url)
(options url opts)

(patch url body)
(patch url body opts)

Client Functions

client-builder

(client-builder)
(client-builder opts)

Creates a new HttpClient builder with optional configuration.

Options:

  • :connect-timeout - Connection timeout in milliseconds or Duration
  • :cookie-handler - CookieHandler instance
  • :executor - Executor for async requests
  • :follow-redirects - Redirect policy (:always, :never, :normal)
  • :priority - Request priority
  • :proxy - ProxySelector instance
  • :ssl-context - SSLContext instance
  • :ssl-parameters - SSLParameters instance
  • :version - HTTP version (:http1.1, :http2)

build-client

(build-client)
(build-client opts)

Builds and returns a configured HttpClient instance.

Convenience Client Builders

(client-with-timeout timeout-ms)
(client-with-version version)
(client-with-redirect-policy redirect-policy)

Response Format

All HTTP responses are returned as Clojure maps with the following keys:

  • :status - HTTP status code (e.g., 200, 404, 500)
  • :headers - Map of response headers
  • :body - Response body (format depends on the :as option)
  • :version - HTTP version used (:http1.1 or :http2)
  • :uri - Request URI

Development

Running Tests

lein test

Building

lein jar

License

Copyright © 2023 Owain Lewis

Distributed under the MIT License.

About

A zero dependency HTTP library built on java.net.http.HttpClient.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published