Liking cljdoc? Tell your friends :D

com.blockether.spel.api

Playwright API testing — APIRequest, APIRequestContext, APIResponse.

Provides idiomatic Clojure wrappers for Playwright's built-in HTTP client. Supports all HTTP methods, form data, query params, custom headers, and lifecycle management via with-api-context.

Usage: (require '[com.blockether.spel.core :as pw] '[com.blockether.spel.api :as api])

(core/with-playwright [playwright] (api/with-api-context [ctx (-> playwright api/api-request (api/new-api-context {:base-url "https://api.example.com"}))] (let [resp (api/get ctx "/users" {:params {:page 1 :limit 10}})] (println (api/response->map resp)))))

;; Response map: ;; {:status 200 ;; :status-text "OK" ;; :url "https://api.example.com/users?page=1&limit=10" ;; :ok? true ;; :headers {"content-type" "application/json"} ;; :body "{...}"}

All HTTP methods accept either a RequestOptions object or a Clojure map:

(api/post ctx "/users" {:headers {"Content-Type" "application/json"} :data "{"name": "Alice"}" :timeout 5000})

(api/put ctx "/users/1" {:form (api/map->form-data {:name "Bob" :email "bob@example.com"})})

(api/delete ctx "/users/1")

Playwright API testing — APIRequest, APIRequestContext, APIResponse.

Provides idiomatic Clojure wrappers for Playwright's built-in HTTP client.
Supports all HTTP methods, form data, query params, custom headers, and
lifecycle management via `with-api-context`.

Usage:
(require '[com.blockether.spel.core :as pw]
         '[com.blockether.spel.api :as api])

(core/with-playwright [playwright]
  (api/with-api-context [ctx (-> playwright api/api-request
                                 (api/new-api-context {:base-url "https://api.example.com"}))]
    (let [resp (api/get ctx "/users" {:params {:page 1 :limit 10}})]
      (println (api/response->map resp)))))

;; Response map:
;; {:status 200
;;  :status-text "OK"
;;  :url "https://api.example.com/users?page=1&limit=10"
;;  :ok? true
;;  :headers {"content-type" "application/json"}
;;  :body "{...}"}

All HTTP methods accept either a RequestOptions object or a Clojure map:

(api/post ctx "/users"
  {:headers {"Content-Type" "application/json"}
   :data    "{\"name\": \"Alice\"}"
   :timeout 5000})

(api/put ctx "/users/1"
  {:form (api/map->form-data {:name "Bob" :email "bob@example.com"})})

(api/delete ctx "/users/1")
raw docstring

*hooks*clj

Map of hook functions invoked during the API request lifecycle.

All hooks are optional (nil = no-op). Each hook receives context about the current operation and can observe or transform it.

Keys:

:on-request (fn [method url opts]) -> opts Called before every request. Receives the HTTP method keyword (:get, :post, ...), the URL string, and the opts map. Return value replaces opts. Return nil to keep original. Use for: logging, auth token injection, request transformation.

:on-response (fn [method url response]) -> response Called after every successful request. Receives the method, URL, and the APIResponse (or response map from request!). Return value replaces the response. Return nil to keep original. Use for: logging, metrics, response transformation.

:on-error (fn [method url anomaly]) -> anomaly Called when a request returns an anomaly (network error, timeout, etc.). Return value replaces the anomaly. Return nil to keep original. Use for: error logging, alerting, error transformation.

:on-retry (fn [{:keys [attempt max-attempts delay-ms result]}]) Called before each retry sleep. Side-effect only, return value ignored. Use for: logging retry attempts, metrics.

Examples:

;; Global logging (alter-var-root #'api/hooks (constantly {:on-request (fn [m url _] (println "→" m url)) :on-response (fn [m url r] (println "←" m url (.status r)) r)}))

;; Per-scope auth injection (binding [api/hooks {:on-request (fn [_ _ opts] (update opts :headers assoc "Authorization" (str "Bearer " (get-token))))}] (api-get ctx "/protected"))

Map of hook functions invoked during the API request lifecycle.

All hooks are optional (nil = no-op). Each hook receives context
about the current operation and can observe or transform it.

Keys:

:on-request   (fn [method url opts]) -> opts
              Called before every request. Receives the HTTP method keyword
              (:get, :post, ...), the URL string, and the opts map.
              Return value replaces opts. Return nil to keep original.
              Use for: logging, auth token injection, request transformation.

:on-response  (fn [method url response]) -> response
              Called after every successful request. Receives the method,
              URL, and the APIResponse (or response map from `request!`).
              Return value replaces the response. Return nil to keep original.
              Use for: logging, metrics, response transformation.

:on-error     (fn [method url anomaly]) -> anomaly
              Called when a request returns an anomaly (network error,
              timeout, etc.). Return value replaces the anomaly.
              Return nil to keep original.
              Use for: error logging, alerting, error transformation.

:on-retry     (fn [{:keys [attempt max-attempts delay-ms result]}])
              Called before each retry sleep. Side-effect only, return
              value ignored.
              Use for: logging retry attempts, metrics.

Examples:

;; Global logging
(alter-var-root #'api/*hooks*
  (constantly
    {:on-request  (fn [m url _] (println "→" m url))
     :on-response (fn [m url r] (println "←" m url (.status r)) r)}))

;; Per-scope auth injection
(binding [api/*hooks* {:on-request (fn [_ _ opts]
                                     (update opts :headers
                                       assoc "Authorization" (str "Bearer " (get-token))))}]
  (api-get ctx "/protected"))
sourceraw docstring

*json-encoder*clj

Function that encodes Clojure data to a JSON string. Bind to your preferred JSON library's encode function.

Must accept any Clojure data (maps, vectors, strings, numbers, etc.) and return a String.

Examples: ;; cheshire (binding [api/json-encoder cheshire.core/generate-string] (api/api-post ctx "/users" {:json {:name "Alice"}}))

;; data.json (binding [api/json-encoder clojure.data.json/write-str] (api/api-post ctx "/users" {:json {:name "Alice"}}))

;; jsonista (binding [api/json-encoder jsonista.core/write-value-as-string] (api/api-post ctx "/users" {:json {:name "Alice"}}))

;; Set globally for convenience (alter-var-root #'api/json-encoder (constantly cheshire.core/generate-string))

Function that encodes Clojure data to a JSON string.
Bind to your preferred JSON library's encode function.

Must accept any Clojure data (maps, vectors, strings, numbers, etc.)
and return a String.

Examples:
;; cheshire
(binding [api/*json-encoder* cheshire.core/generate-string]
  (api/api-post ctx "/users" {:json {:name "Alice"}}))

;; data.json
(binding [api/*json-encoder* clojure.data.json/write-str]
  (api/api-post ctx "/users" {:json {:name "Alice"}}))

;; jsonista
(binding [api/*json-encoder* jsonista.core/write-value-as-string]
  (api/api-post ctx "/users" {:json {:name "Alice"}}))

;; Set globally for convenience
(alter-var-root #'api/*json-encoder* (constantly cheshire.core/generate-string))
sourceraw docstring

api-deleteclj

(api-delete ctx url)
(api-delete ctx url opts)

Sends a DELETE request.

Params: ctx - APIRequestContext instance. url - String. URL path. opts - RequestOptions or map, optional. See request-options.

Returns: APIResponse or anomaly map.

Sends a DELETE request.

Params:
`ctx`  - APIRequestContext instance.
`url`  - String. URL path.
`opts` - RequestOptions or map, optional. See `request-options`.

Returns:
APIResponse or anomaly map.
sourceraw docstring

api-dispose!clj

(api-dispose! ctx)

Disposes the APIRequestContext and all responses.

Params: ctx - APIRequestContext instance.

Returns: nil.

Disposes the APIRequestContext and all responses.

Params:
`ctx` - APIRequestContext instance.

Returns:
nil.
sourceraw docstring

api-fetchclj

(api-fetch ctx url)
(api-fetch ctx url opts)

Sends a request with custom method (set via :method in opts).

Params: ctx - APIRequestContext instance. url - String. URL path. opts - RequestOptions or map, optional. See request-options.

Returns: APIResponse or anomaly map.

Examples: (api-fetch ctx "/resource" {:method "OPTIONS"})

Sends a request with custom method (set via :method in opts).

Params:
`ctx`  - APIRequestContext instance.
`url`  - String. URL path.
`opts` - RequestOptions or map, optional. See `request-options`.

Returns:
APIResponse or anomaly map.

Examples:
(api-fetch ctx "/resource" {:method "OPTIONS"})
sourceraw docstring

api-getclj

(api-get ctx url)
(api-get ctx url opts)

Sends a GET request.

Params: ctx - APIRequestContext instance. url - String. URL path (resolved against base-url if set). opts - RequestOptions or map, optional. See request-options.

Returns: APIResponse or anomaly map.

Examples: (api-get ctx "/users") (api-get ctx "/users" {:params {:page 1 :limit 10} :headers {"Authorization" "Bearer token"}})

Sends a GET request.

Params:
`ctx`  - APIRequestContext instance.
`url`  - String. URL path (resolved against base-url if set).
`opts` - RequestOptions or map, optional. See `request-options`.

Returns:
APIResponse or anomaly map.

Examples:
(api-get ctx "/users")
(api-get ctx "/users" {:params {:page 1 :limit 10}
                         :headers {"Authorization" "Bearer token"}})
sourceraw docstring

api-headclj

(api-head ctx url)
(api-head ctx url opts)

Sends a HEAD request.

Params: ctx - APIRequestContext instance. url - String. URL path. opts - RequestOptions or map, optional. See request-options.

Returns: APIResponse or anomaly map.

Sends a HEAD request.

Params:
`ctx`  - APIRequestContext instance.
`url`  - String. URL path.
`opts` - RequestOptions or map, optional. See `request-options`.

Returns:
APIResponse or anomaly map.
sourceraw docstring

api-patchclj

(api-patch ctx url)
(api-patch ctx url opts)

Sends a PATCH request.

Params: ctx - APIRequestContext instance. url - String. URL path. opts - RequestOptions or map, optional. See request-options.

Returns: APIResponse or anomaly map.

Sends a PATCH request.

Params:
`ctx`  - APIRequestContext instance.
`url`  - String. URL path.
`opts` - RequestOptions or map, optional. See `request-options`.

Returns:
APIResponse or anomaly map.
sourceraw docstring

api-postclj

(api-post ctx url)
(api-post ctx url opts)

Sends a POST request.

Params: ctx - APIRequestContext instance. url - String. URL path. opts - RequestOptions or map, optional. See request-options.

Returns: APIResponse or anomaly map.

Examples: (api-post ctx "/users" {:data "{"name": "Alice"}" :headers {"Content-Type" "application/json"}}) (api-post ctx "/login" {:form (map->form-data {:user "admin" :pass "secret"})})

Sends a POST request.

Params:
`ctx`  - APIRequestContext instance.
`url`  - String. URL path.
`opts` - RequestOptions or map, optional. See `request-options`.

Returns:
APIResponse or anomaly map.

Examples:
(api-post ctx "/users" {:data "{\"name\": \"Alice\"}"
                           :headers {"Content-Type" "application/json"}})
(api-post ctx "/login" {:form (map->form-data {:user "admin" :pass "secret"})})
sourceraw docstring

api-putclj

(api-put ctx url)
(api-put ctx url opts)

Sends a PUT request.

Params: ctx - APIRequestContext instance. url - String. URL path. opts - RequestOptions or map, optional. See request-options.

Returns: APIResponse or anomaly map.

Sends a PUT request.

Params:
`ctx`  - APIRequestContext instance.
`url`  - String. URL path.
`opts` - RequestOptions or map, optional. See `request-options`.

Returns:
APIResponse or anomaly map.
sourceraw docstring

api-requestclj

(api-request pw)

Returns the APIRequest for the Playwright instance.

Params: pw - Playwright instance.

Returns: APIRequest instance.

Returns the APIRequest for the Playwright instance.

Params:
`pw` - Playwright instance.

Returns:
APIRequest instance.
sourceraw docstring

api-response->mapclj

(api-response->map resp)

Converts an APIResponse to a Clojure map.

Reads the response body as text and includes all metadata. Useful for logging, debugging, and test assertions.

Params: resp - APIResponse instance.

Returns: Map with keys: :status - Long. HTTP status code. :status-text - String. HTTP status text. :url - String. Response URL. :ok? - Boolean. True if status is 2xx. :headers - Map. Response headers. :body - String. Response body text (nil on read failure).

Examples: (let [resp (api-get ctx "/users")] (api-response->map resp)) ;; => {:status 200 ;; :status-text "OK" ;; :url "https://api.example.com/users" ;; :ok? true ;; :headers {"content-type" "application/json"} ;; :body "{"users": [...]}"}

Converts an APIResponse to a Clojure map.

Reads the response body as text and includes all metadata.
Useful for logging, debugging, and test assertions.

Params:
`resp` - APIResponse instance.

Returns:
Map with keys:
  :status      - Long. HTTP status code.
  :status-text - String. HTTP status text.
  :url         - String. Response URL.
  :ok?         - Boolean. True if status is 2xx.
  :headers     - Map. Response headers.
  :body        - String. Response body text (nil on read failure).

Examples:
(let [resp (api-get ctx "/users")]
  (api-response->map resp))
;; => {:status 200
;;     :status-text "OK"
;;     :url "https://api.example.com/users"
;;     :ok? true
;;     :headers {"content-type" "application/json"}
 ;;     :body "{\"users\": [...]}"}
sourceraw docstring

api-response-bodyclj

(api-response-body resp)

Returns the response body as bytes. Passes through anomaly maps unchanged.

Returns the response body as bytes.
Passes through anomaly maps unchanged.
sourceraw docstring

api-response-dispose!clj

(api-response-dispose! resp)

Disposes the APIResponse. No-op on anomaly maps.

Params: resp - APIResponse instance.

Returns: nil.

Disposes the APIResponse.
No-op on anomaly maps.

Params:
`resp` - APIResponse instance.

Returns:
nil.
sourceraw docstring

api-response-headersclj

(api-response-headers resp)

Returns the response headers. Passes through anomaly maps unchanged.

Returns the response headers.
Passes through anomaly maps unchanged.
sourceraw docstring

api-response-headers-arrayclj

(api-response-headers-array resp)

Returns the response headers as a vector of {:name :value} maps. Preserves duplicate headers (unlike api-response-headers which keeps only the last value for each name). Passes through anomaly maps unchanged.

Params: resp - APIResponse instance.

Returns: Vector of maps, or anomaly map.

Returns the response headers as a vector of {:name :value} maps.
Preserves duplicate headers (unlike `api-response-headers` which
keeps only the last value for each name).
Passes through anomaly maps unchanged.

Params:
`resp` - APIResponse instance.

Returns:
Vector of maps, or anomaly map.
sourceraw docstring

api-response-ok?clj

(api-response-ok? resp)

Returns whether the response is OK (2xx). Passes through anomaly maps unchanged.

Returns whether the response is OK (2xx).
Passes through anomaly maps unchanged.
sourceraw docstring

api-response-statusclj

(api-response-status resp)

Returns the HTTP status code. Passes through anomaly maps unchanged.

Returns the HTTP status code.
Passes through anomaly maps unchanged.
sourceraw docstring

api-response-status-textclj

(api-response-status-text resp)

Returns the HTTP status text. Passes through anomaly maps unchanged.

Returns the HTTP status text.
Passes through anomaly maps unchanged.
sourceraw docstring

api-response-textclj

(api-response-text resp)

Returns the response body as text. Passes through anomaly maps unchanged.

Returns the response body as text.
Passes through anomaly maps unchanged.
sourceraw docstring

api-response-urlclj

(api-response-url resp)

Returns the response URL. Passes through anomaly maps unchanged.

Returns the response URL.
Passes through anomaly maps unchanged.
sourceraw docstring

default-retry-optsclj

Default retry configuration.

:max-attempts - Total attempts including the first (default: 3). :delay-ms - Initial delay between retries in ms (default: 200). :backoff - Backoff strategy (default: :exponential). :fixed — constant delay. :linear — delay * attempt. :exponential — delay * 2^attempt. :max-delay-ms - Ceiling on delay (default: 10000). :retry-when - Predicate (fn [result] -> truthy to retry). Default: retries on anomalies and 5xx status codes.

Default retry configuration.

:max-attempts  - Total attempts including the first (default: 3).
:delay-ms      - Initial delay between retries in ms (default: 200).
:backoff       - Backoff strategy (default: :exponential).
                 :fixed        — constant delay.
                 :linear       — delay * attempt.
                 :exponential  — delay * 2^attempt.
:max-delay-ms  - Ceiling on delay (default: 10000).
:retry-when    - Predicate (fn [result] -> truthy to retry).
                 Default: retries on anomalies and 5xx status codes.
sourceraw docstring

fd-appendclj

(fd-append fd name value)

Appends a field to FormData.

Params: fd - FormData instance. name - String. Field name. value - String. Field value.

Returns: FormData instance.

Appends a field to FormData.

Params:
`fd`    - FormData instance.
`name`  - String. Field name.
`value` - String. Field value.

Returns:
FormData instance.
sourceraw docstring

fd-setclj

(fd-set fd name value)

Sets a field in FormData.

Params: fd - FormData instance. name - String. Field name. value - String. Field value.

Returns: FormData instance.

Sets a field in FormData.

Params:
`fd`    - FormData instance.
`name`  - String. Field name.
`value` - String. Field value.

Returns:
FormData instance.
sourceraw docstring

form-dataclj

(form-data)

Creates a new FormData instance.

Returns: FormData instance.

Creates a new FormData instance.

Returns:
FormData instance.
sourceraw docstring

map->form-dataclj

(map->form-data m)

Converts a Clojure map to FormData.

Params: m - Map of string->string.

Returns: FormData instance.

Converts a Clojure map to FormData.

Params:
`m` - Map of string->string.

Returns:
FormData instance.
sourceraw docstring

new-api-contextclj

(new-api-context api-req)
(new-api-context api-req opts)

Creates a new APIRequestContext.

Params: api-req - APIRequest instance (from api-request). opts - Map, optional. Context options: :base-url - String. Base URL for all requests. :extra-http-headers - Map. Headers sent with every request. :ignore-https-errors - Boolean. Ignore SSL certificate errors. :timeout - Double. Default timeout in ms (default: 30000). :user-agent - String. User-Agent header. :max-redirects - Long. Max redirects to follow (default: 20). :fail-on-status-code - Boolean. Throw on non-2xx/3xx status. :storage-state - String. Storage state JSON or path.

Returns: APIRequestContext or anomaly map.

Examples: (new-api-context (api-request pw) {:base-url "https://api.example.com" :extra-http-headers {"Authorization" "Bearer token"} :timeout 10000})

Creates a new APIRequestContext.

Params:
`api-req` - APIRequest instance (from `api-request`).
`opts`    - Map, optional. Context options:
  :base-url            - String. Base URL for all requests.
  :extra-http-headers  - Map. Headers sent with every request.
  :ignore-https-errors - Boolean. Ignore SSL certificate errors.
  :timeout             - Double. Default timeout in ms (default: 30000).
  :user-agent          - String. User-Agent header.
  :max-redirects       - Long. Max redirects to follow (default: 20).
  :fail-on-status-code - Boolean. Throw on non-2xx/3xx status.
  :storage-state       - String. Storage state JSON or path.

Returns:
APIRequestContext or anomaly map.

Examples:
(new-api-context (api-request pw)
  {:base-url "https://api.example.com"
   :extra-http-headers {"Authorization" "Bearer token"}
   :timeout 10000})
sourceraw docstring

request!clj

(request! pw method url)
(request! pw method url opts)

Fire-and-forget HTTP request. Creates an ephemeral context, makes the request, reads the full response into a Clojure map, and disposes everything. No context management needed.

Params: pw - Playwright instance. method - Keyword. :get :post :put :patch :delete :head. url - String. Full URL (not relative — no base-url). opts - Map, optional. See request-options for all keys.

Returns: Response map (same shape as api-response->map) or anomaly map.

Examples: ;; Simple GET — no setup, no cleanup (request! pw :get "https://api.example.com/health") ;; => {:status 200 :ok? true :body "OK" ...}

;; POST with JSON body (request! pw :post "https://api.example.com/users" {:data "{"name": "Alice"}" :headers {"Content-Type" "application/json" "Authorization" "Bearer token"}})

;; Hit multiple domains without any context setup (let [users (request! pw :get "https://users.example.com/me" {:headers {"Authorization" "Bearer user-token"}}) invoices (request! pw :get "https://billing.example.com/invoices" {:headers {"X-API-Key" "billing-key"}})] [users invoices])

Fire-and-forget HTTP request. Creates an ephemeral context, makes the
request, reads the full response into a Clojure map, and disposes
everything. No context management needed.

Params:
`pw`     - Playwright instance.
`method` - Keyword. :get :post :put :patch :delete :head.
`url`    - String. Full URL (not relative — no base-url).
`opts`   - Map, optional. See `request-options` for all keys.

Returns:
Response map (same shape as `api-response->map`) or anomaly map.

Examples:
;; Simple GET — no setup, no cleanup
(request! pw :get "https://api.example.com/health")
;; => {:status 200 :ok? true :body "OK" ...}

;; POST with JSON body
(request! pw :post "https://api.example.com/users"
  {:data    "{\"name\": \"Alice\"}"
   :headers {"Content-Type" "application/json"
             "Authorization" "Bearer token"}})

;; Hit multiple domains without any context setup
(let [users    (request! pw :get "https://users.example.com/me"
                 {:headers {"Authorization" "Bearer user-token"}})
      invoices (request! pw :get "https://billing.example.com/invoices"
                 {:headers {"X-API-Key" "billing-key"}})]
  [users invoices])
sourceraw docstring

request-optionsclj

(request-options opts)

Creates RequestOptions from a map.

Params: opts - Map with optional: :method - String. HTTP method override. :headers - Map. HTTP headers ({"Authorization" "Bearer ..."}). :data - String, bytes, or Object. Request body. Objects are auto-serialized to JSON by Playwright. :json - Any Clojure data. Encoded via *json-encoder*, sets Content-Type to application/json automatically. Mutually exclusive with :data, :form, :multipart. :form - FormData. URL-encoded form data. :multipart - FormData. Multipart form data (file uploads). :timeout - Double. Timeout in ms (default: 30000). :params - Map. Query parameters. :max-redirects - Long. Max redirects to follow (default: 20). :max-retries - Long. Retry network errors (default: 0). :fail-on-status-code - Boolean. Throw on non-2xx/3xx status. :ignore-https-errors - Boolean. Ignore SSL certificate errors.

The :json key requires *json-encoder* to be bound:

(binding [api/json-encoder cheshire.core/generate-string] (api/api-post ctx "/users" {:json {:name "Alice" :age 30}}))

Returns: RequestOptions instance.

Creates RequestOptions from a map.

Params:
`opts` - Map with optional:
  :method              - String. HTTP method override.
  :headers             - Map. HTTP headers ({"Authorization" "Bearer ..."}).
  :data                - String, bytes, or Object. Request body.
                         Objects are auto-serialized to JSON by Playwright.
  :json                - Any Clojure data. Encoded via `*json-encoder*`,
                         sets Content-Type to application/json automatically.
                         Mutually exclusive with :data, :form, :multipart.
  :form                - FormData. URL-encoded form data.
  :multipart           - FormData. Multipart form data (file uploads).
  :timeout             - Double. Timeout in ms (default: 30000).
  :params              - Map. Query parameters.
  :max-redirects       - Long. Max redirects to follow (default: 20).
  :max-retries         - Long. Retry network errors (default: 0).
  :fail-on-status-code - Boolean. Throw on non-2xx/3xx status.
  :ignore-https-errors - Boolean. Ignore SSL certificate errors.

The :json key requires `*json-encoder*` to be bound:

  (binding [api/*json-encoder* cheshire.core/generate-string]
    (api/api-post ctx "/users" {:json {:name "Alice" :age 30}}))

Returns:
RequestOptions instance.
sourceraw docstring

retryclj

(retry f)
(retry f opts)

Execute f (a no-arg function) with retry logic.

Params: f - No-arg function that returns a result. opts - Map, optional. Override keys from default-retry-opts: :max-attempts - Total attempts (default: 3). :delay-ms - Initial delay in ms (default: 200). :backoff - :fixed, :linear, or :exponential (default). :max-delay-ms - Max delay ceiling in ms (default: 10000). :retry-when - (fn [result]) → truthy to retry.

Returns: The result of the last attempt.

Examples: ;; Retry a flaky endpoint (retry #(api-get ctx "/flaky"))

;; Custom: retry on 429 Too Many Requests with linear backoff (retry #(api-get ctx "/rate-limited") {:max-attempts 5 :delay-ms 1000 :backoff :linear :retry-when (fn [r] (= 429 (:status (api-response->map r))))})

Execute `f` (a no-arg function) with retry logic.

Params:
`f`    - No-arg function that returns a result.
`opts` - Map, optional. Override keys from `default-retry-opts`:
  :max-attempts  - Total attempts (default: 3).
  :delay-ms      - Initial delay in ms (default: 200).
  :backoff       - :fixed, :linear, or :exponential (default).
  :max-delay-ms  - Max delay ceiling in ms (default: 10000).
  :retry-when    - (fn [result]) → truthy to retry.

Returns:
The result of the last attempt.

Examples:
;; Retry a flaky endpoint
(retry #(api-get ctx "/flaky"))

;; Custom: retry on 429 Too Many Requests with linear backoff
(retry #(api-get ctx "/rate-limited")
  {:max-attempts 5
   :delay-ms     1000
   :backoff      :linear
   :retry-when   (fn [r] (= 429 (:status (api-response->map r))))})
sourceraw docstring

with-api-contextcljmacro

(with-api-context [sym expr] & body)

Binds a single APIRequestContext and ensures disposal.

Usage: (with-api-context [ctx (new-api-context (api-request pw) {:base-url "https://api.example.com"})] (api-get ctx "/users"))

Binds a single APIRequestContext and ensures disposal.

Usage:
(with-api-context [ctx (new-api-context (api-request pw) {:base-url "https://api.example.com"})]
  (api-get ctx "/users"))
sourceraw docstring

with-api-contextscljmacro

(with-api-contexts bindings & body)

Binds multiple APIRequestContexts and disposes all on exit.

Same shape as with-open — flat pairs of [name expr].

Usage: (with-api-contexts [users (new-api-context (api-request pw) {:base-url "https://users.example.com" :extra-http-headers {"Authorization" "Bearer token"}}) billing (new-api-context (api-request pw) {:base-url "https://billing.example.com" :extra-http-headers {"X-API-Key" "key"}}) public (new-api-context (api-request pw) {:base-url "https://public.example.com"})] (api-get users "/me") (api-get billing "/invoices") (api-get public "/catalog"))

Binds multiple APIRequestContexts and disposes all on exit.

Same shape as `with-open` — flat pairs of [name expr].

Usage:
(with-api-contexts [users   (new-api-context (api-request pw)
                              {:base-url "https://users.example.com"
                               :extra-http-headers {"Authorization" "Bearer token"}})
                    billing (new-api-context (api-request pw)
                              {:base-url "https://billing.example.com"
                               :extra-http-headers {"X-API-Key" "key"}})
                    public  (new-api-context (api-request pw)
                              {:base-url "https://public.example.com"})]
  (api-get users "/me")
  (api-get billing "/invoices")
  (api-get public "/catalog"))
sourceraw docstring

with-hookscljmacro

(with-hooks hooks & body)

Execute body with the given hooks merged into *hooks*.

Merges with (not replaces) any existing hooks so outer bindings are preserved for keys you don't override.

Usage: (with-hooks {:on-request (fn [m url opts] (log/info m url) opts) :on-response (fn [m url resp] (metrics/inc! :api-calls) resp)} (api-get ctx "/users") (api-post ctx "/users" {:json {:name "Alice"}}))

Execute body with the given hooks merged into `*hooks*`.

Merges with (not replaces) any existing hooks so outer bindings
are preserved for keys you don't override.

Usage:
(with-hooks {:on-request  (fn [m url opts] (log/info m url) opts)
             :on-response (fn [m url resp] (metrics/inc! :api-calls) resp)}
  (api-get ctx "/users")
  (api-post ctx "/users" {:json {:name "Alice"}}))
sourceraw docstring

with-retrycljmacro

(with-retry opts-or-body & body)

Execute body with retry logic.

Usage: ;; Default: 3 attempts, exponential backoff, retry on anomalies + 5xx (with-retry {} (api-get ctx "/flaky-endpoint"))

;; Custom retry config (with-retry {:max-attempts 5 :delay-ms 500 :backoff :linear :retry-when (fn [r] (and (map? r) (>= (:status r) 500)))} (api-post ctx "/idempotent-endpoint" {:json {:action "process"}}))

;; Retry standalone requests too (with-retry {:max-attempts 3} (request! pw :get "https://api.example.com/health"))

Execute body with retry logic.

Usage:
;; Default: 3 attempts, exponential backoff, retry on anomalies + 5xx
(with-retry {}
  (api-get ctx "/flaky-endpoint"))

;; Custom retry config
(with-retry {:max-attempts 5
             :delay-ms     500
             :backoff      :linear
             :retry-when   (fn [r] (and (map? r) (>= (:status r) 500)))}
  (api-post ctx "/idempotent-endpoint"
    {:json {:action "process"}}))

;; Retry standalone requests too
(with-retry {:max-attempts 3}
  (request! pw :get "https://api.example.com/health"))
sourceraw docstring

cljdoc builds & hosts documentation for Clojure/Script libraries

Keyboard shortcuts
Ctrl+kJump to recent docs
Move to previous article
Move to next article
Ctrl+/Jump to the search field
× close