{"id":17304010,"url":"https://github.com/owainlewis/java-http-clj","last_synced_at":"2025-07-31T12:30:47.602Z","repository":{"id":62431925,"uuid":"198895107","full_name":"owainlewis/java-http-clj","owner":"owainlewis","description":"A zero dependency HTTP library built on java.net.http.HttpClient.","archived":false,"fork":false,"pushed_at":"2025-03-14T12:08:54.000Z","size":59,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-06-24T16:24:30.531Z","etag":null,"topics":["clojure","clojure-http","http","http-client","java"],"latest_commit_sha":null,"homepage":"","language":"Clojure","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"epl-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/owainlewis.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-07-25T20:10:30.000Z","updated_at":"2025-03-14T12:08:57.000Z","dependencies_parsed_at":"2022-11-01T20:46:39.637Z","dependency_job_id":null,"html_url":"https://github.com/owainlewis/java-http-clj","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/owainlewis/java-http-clj","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/owainlewis%2Fjava-http-clj","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/owainlewis%2Fjava-http-clj/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/owainlewis%2Fjava-http-clj/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/owainlewis%2Fjava-http-clj/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/owainlewis","download_url":"https://codeload.github.com/owainlewis/java-http-clj/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/owainlewis%2Fjava-http-clj/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":267988484,"owners_count":24176996,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-07-31T02:00:08.723Z","response_time":66,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["clojure","clojure-http","http","http-client","java"],"created_at":"2024-10-15T11:51:57.640Z","updated_at":"2025-07-31T12:30:47.588Z","avatar_url":"https://github.com/owainlewis.png","language":"Clojure","funding_links":[],"categories":[],"sub_categories":[],"readme":"# java-http-clj\n\n[![Clojars Project](https://img.shields.io/clojars/v/com.owainlewis/java-http-clj.svg)](https://clojars.org/com.owainlewis/java-http-clj)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n\nA 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.\n\n## Features\n\n- Simple, idiomatic Clojure API\n- Synchronous and asynchronous requests\n- Support for all HTTP methods (GET, POST, PUT, DELETE, etc.)\n- Customizable client configuration (timeouts, redirects, etc.)\n- Support for different response body types (string, bytes, stream)\n- Basic authentication support\n- Built on the modern Java 11+ HTTP client for performance and reliability\n\n## Requirements\n\n- Java 11 or higher\n- Clojure 1.10 or higher\n\n## Installation\n\nAdd the following dependency to your project.clj:\n\n```clojure\n[com.owainlewis/java-http-clj \"0.3.1-SNAPSHOT\"]\n```\n\nOr with deps.edn:\n\n```clojure\n{:deps {com.owainlewis/java-http-clj {:mvn/version \"0.3.1-SNAPSHOT\"}}}\n```\n\n## Quick Start\n\n```clojure\n(require '[java-http-clj.core :as http])\n\n;; Simple GET request\n(http/get \"https://api.example.com/users\")\n\n;; POST request with JSON body\n(http/post \"https://api.example.com/users\" \n           \"{\\\"name\\\": \\\"John\\\", \\\"email\\\": \\\"john@example.com\\\"}\" \n           {:headers {\"Content-Type\" \"application/json\"}})\n\n;; Asynchronous request with callback\n(http/async-request \n  {:method :get :url \"https://api.example.com/users\"} \n  {} \n  (fn [response] (println \"Got response:\" (:status response))))\n```\n\n## Usage Examples\n\n### Basic Requests\n\n```clojure\n(require '[java-http-clj.core :as http])\n\n;; GET request\n(http/get \"https://api.example.com/users\")\n\n;; POST request with body\n(http/post \"https://api.example.com/users\" \"Hello, world!\")\n\n;; PUT request\n(http/put \"https://api.example.com/users/123\" \"{\\\"name\\\": \\\"Updated Name\\\"}\")\n\n;; DELETE request\n(http/delete \"https://api.example.com/users/123\")\n\n;; HEAD request\n(http/head \"https://api.example.com/users\")\n\n;; OPTIONS request\n(http/options \"https://api.example.com/users\")\n\n;; PATCH request\n(http/patch \"https://api.example.com/users/123\" \"{\\\"name\\\": \\\"Patched Name\\\"}\")\n```\n\n### Request with Headers\n\n```clojure\n(http/get \"https://api.example.com/users\" \n          {:headers {\"Authorization\" \"Bearer token123\"\n                     \"Accept\" \"application/json\"}})\n```\n\n### Basic Authentication\n\n```clojure\n(http/get \"https://api.example.com/protected\" \n          {:basic-auth [\"username\" \"password\"]})\n\n;; Or with the request map\n(http/request {:method :get\n               :url \"https://api.example.com/protected\"\n               :basic-auth [\"username\" \"password\"]})\n```\n\n### Custom Timeout\n\n```clojure\n;; Set request timeout (in milliseconds)\n(http/get \"https://api.example.com/slow-endpoint\" \n          {:timeout 5000})\n```\n\n### Response Body Handling\n\n```clojure\n;; Get response as string (default)\n(http/get \"https://api.example.com/users\" \n          {:as :string})\n\n;; Get response as byte array\n(http/get \"https://api.example.com/image.jpg\" \n          {:as :bytes})\n\n;; Get response as input stream\n(http/get \"https://api.example.com/large-file\" \n          {:as :stream})\n\n;; Discard response body\n(http/head \"https://api.example.com/users\" \n           {:as :discard})\n```\n\n### Asynchronous Requests\n\n```clojure\n;; With callback\n(http/async-request \n  {:method :get :url \"https://api.example.com/users\"} \n  {} \n  (fn [response] \n    (println \"Status:\" (:status response))\n    (println \"Body:\" (:body response))))\n\n;; Without callback (returns CompletableFuture)\n(def future-response \n  (http/async-request \n    {:method :get :url \"https://api.example.com/users\"}))\n\n;; Later, get the result\n(def response (.get future-response))\n```\n\n### Custom Client Configuration\n\n```clojure\n(require '[java-http-clj.client :as client])\n\n;; Create a custom client\n(def custom-client \n  (client/build-client \n    {:connect-timeout 5000\n     :follow-redirects :always\n     :version :http2}))\n\n;; Use the custom client\n(http/get \"https://api.example.com/users\" \n          {:client custom-client})\n\n;; Convenience functions for common configurations\n(def timeout-client (client/client-with-timeout 5000))\n(def http2-client (client/client-with-version :http2))\n(def redirect-client (client/client-with-redirect-policy :always))\n```\n\n## API Documentation\n\n### Core Functions\n\n#### `request`\n\n```clojure\n(request req)\n(request req opts)\n```\n\nMakes an HTTP request and returns the response.\n\nRequest map options:\n- `:method` - HTTP method (`:get`, `:post`, `:put`, `:delete`, etc.)\n- `:url` - URL string\n- `:headers` - Map of headers\n- `:body` - Request body (String, byte[], InputStream, or Path)\n- `:basic-auth` - Vector of [username password]\n- `:timeout` - Request timeout in milliseconds\n\nClient options:\n- `:client` - HttpClient instance to use\n- `:timeout` - Connection timeout in milliseconds\n- `:follow-redirects` - Redirect policy (`:always`, `:never`, `:normal`)\n- `:version` - HTTP version (`:http1.1`, `:http2`)\n- `:as` - Response body type (`:string`, `:bytes`, `:stream`, `:discard`)\n\n#### `async-request`\n\n```clojure\n(async-request req)\n(async-request req opts)\n(async-request req opts callback)\n```\n\nMakes 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.\n\n#### HTTP Method Helpers\n\n```clojure\n(get url)\n(get url opts)\n\n(post url body)\n(post url body opts)\n\n(put url body)\n(put url body opts)\n\n(delete url)\n(delete url opts)\n\n(head url)\n(head url opts)\n\n(options url)\n(options url opts)\n\n(patch url body)\n(patch url body opts)\n```\n\n### Client Functions\n\n#### `client-builder`\n\n```clojure\n(client-builder)\n(client-builder opts)\n```\n\nCreates a new HttpClient builder with optional configuration.\n\nOptions:\n- `:connect-timeout` - Connection timeout in milliseconds or Duration\n- `:cookie-handler` - CookieHandler instance\n- `:executor` - Executor for async requests\n- `:follow-redirects` - Redirect policy (`:always`, `:never`, `:normal`)\n- `:priority` - Request priority\n- `:proxy` - ProxySelector instance\n- `:ssl-context` - SSLContext instance\n- `:ssl-parameters` - SSLParameters instance\n- `:version` - HTTP version (`:http1.1`, `:http2`)\n\n#### `build-client`\n\n```clojure\n(build-client)\n(build-client opts)\n```\n\nBuilds and returns a configured HttpClient instance.\n\n#### Convenience Client Builders\n\n```clojure\n(client-with-timeout timeout-ms)\n(client-with-version version)\n(client-with-redirect-policy redirect-policy)\n```\n\n## Response Format\n\nAll HTTP responses are returned as Clojure maps with the following keys:\n\n- `:status` - HTTP status code (e.g., 200, 404, 500)\n- `:headers` - Map of response headers\n- `:body` - Response body (format depends on the `:as` option)\n- `:version` - HTTP version used (`:http1.1` or `:http2`)\n- `:uri` - Request URI\n\n## Development\n\n### Running Tests\n\n```bash\nlein test\n```\n\n### Building\n\n```bash\nlein jar\n```\n\n## License\n\nCopyright © 2023 Owain Lewis\n\nDistributed under the MIT License.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fowainlewis%2Fjava-http-clj","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fowainlewis%2Fjava-http-clj","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fowainlewis%2Fjava-http-clj/lists"}