Composable HTTP request builder and executor for Supabase services.
Requests are built as plain maps using a threading-friendly API, then executed synchronously via Hato. This is the backbone that all service modules (auth, storage, postgrest, functions, realtime) use internally.
A request map contains:
:method — HTTP method keyword (:get, :post, :put, :patch, :delete):url — fully resolved URL string:headers — map of header name to value:query — map of query parameter name to value:body — request body (map, string, or nil):service — originating service keyword (:auth, :storage, etc.):client — reference to the client map(require '[supabase.core.http :as http])
;; Build and execute a request
(-> (http/request client)
(http/with-service-url :auth-url "/signup")
(http/with-method :post)
(http/with-body {:email "user@example.com" :password "secret"})
(http/execute))
;; Returns {:status 200, :body {...}, :headers {...}} on success
;; Returns anomaly map on HTTP error (status >= 400)
;; Throwing variant for those who prefer exceptions
(-> (http/request client)
(http/with-service-url :auth-url "/signup")
(http/with-method :post)
(http/with-body {:email "user@example.com" :password "secret"})
(http/execute!))
;; Async variant returning CompletableFuture
(-> (http/request client)
(http/with-service-url :functions-url "/hello")
(http/with-method :post)
(http/with-body {:name "world"})
(http/execute-async))
Composable HTTP request builder and executor for Supabase services.
Requests are built as plain maps using a threading-friendly API, then
executed synchronously via Hato. This is the backbone that all service
modules (auth, storage, postgrest, functions, realtime) use internally.
## Request Map Structure
A request map contains:
- `:method` — HTTP method keyword (`:get`, `:post`, `:put`, `:patch`, `:delete`)
- `:url` — fully resolved URL string
- `:headers` — map of header name to value
- `:query` — map of query parameter name to value
- `:body` — request body (map, string, or nil)
- `:service` — originating service keyword (`:auth`, `:storage`, etc.)
- `:client` — reference to the client map
## Usage
(require '[supabase.core.http :as http])
;; Build and execute a request
(-> (http/request client)
(http/with-service-url :auth-url "/signup")
(http/with-method :post)
(http/with-body {:email "user@example.com" :password "secret"})
(http/execute))
;; Returns {:status 200, :body {...}, :headers {...}} on success
;; Returns anomaly map on HTTP error (status >= 400)
;; Throwing variant for those who prefer exceptions
(-> (http/request client)
(http/with-service-url :auth-url "/signup")
(http/with-method :post)
(http/with-body {:email "user@example.com" :password "secret"})
(http/execute!))
;; Async variant returning CompletableFuture
(-> (http/request client)
(http/with-service-url :functions-url "/hello")
(http/with-method :post)
(http/with-body {:name "world"})
(http/execute-async))(execute {:keys [service] :as req})Executes the request synchronously via Hato.
Returns a response map on success (status < 400) or an anomaly map on error.
(-> (request client)
(with-service-url :auth-url "/token")
(with-method :post)
(with-body {:grant-type "password" :email "a@b.com" :password "x"})
(execute))
;; => {:status 200, :body {...}, :headers {...}}
Executes the request synchronously via Hato.
Returns a response map on success (status < 400) or an anomaly map on error.
(-> (request client)
(with-service-url :auth-url "/token")
(with-method :post)
(with-body {:grant-type "password" :email "a@b.com" :password "x"})
(execute))
;; => {:status 200, :body {...}, :headers {...}}(execute! req)Like execute, but throws an ex-info on error instead of returning an anomaly map.
The anomaly map is attached as the ex-data of the thrown exception.
(try
(-> (request client)
(with-service-url :auth-url "/token")
(with-method :post)
(execute!))
(catch Exception e
(ex-data e))) ;; => anomaly map
Like `execute`, but throws an `ex-info` on error instead of returning an anomaly map.
The anomaly map is attached as the ex-data of the thrown exception.
(try
(-> (request client)
(with-service-url :auth-url "/token")
(with-method :post)
(execute!))
(catch Exception e
(ex-data e))) ;; => anomaly map(execute-async {:keys [service] :as req})Executes the request asynchronously, returning a CompletableFuture.
The future completes with the same value execute would return — either
a response map or an anomaly map.
@(-> (request client)
(with-service-url :functions-url "/hello")
(with-method :post)
(with-body {:name "world"})
(execute-async))
Executes the request asynchronously, returning a `CompletableFuture`.
The future completes with the same value `execute` would return — either
a response map or an anomaly map.
@(-> (request client)
(with-service-url :functions-url "/hello")
(with-method :post)
(with-body {:name "world"})
(execute-async))(request client)Initializes a request map from a client, pre-populating auth headers.
The request starts with :method :get and includes the client's global
headers plus authorization and apikey headers derived from the client.
(request client)
;; => {:method :get, :headers {...}, :client client, ...}
Initializes a request map from a client, pre-populating auth headers.
The request starts with `:method :get` and includes the client's global
headers plus `authorization` and `apikey` headers derived from the client.
(request client)
;; => {:method :get, :headers {...}, :client client, ...}(with-body req body)Sets the request body. Maps are JSON-encoded automatically. Strings and nil are passed through as-is.
(with-body req {:email "user@example.com"})
Sets the request body. Maps are JSON-encoded automatically.
Strings and nil are passed through as-is.
(with-body req {:email "user@example.com"})(with-headers req headers)Merges additional headers into the request. Later values override earlier ones for the same header name.
(with-headers req {"prefer" "return=representation"})
Merges additional headers into the request. Later values override earlier
ones for the same header name.
(with-headers req {"prefer" "return=representation"})(with-method req method)Sets the HTTP method for the request.
(with-method req :post)
Sets the HTTP method for the request. (with-method req :post)
(with-query req params)Merges query parameters into the request. Later values override earlier ones for the same parameter name.
(with-query req {"select" "*" "order" "id.asc"})
Merges query parameters into the request. Later values override earlier
ones for the same parameter name.
(with-query req {"select" "*" "order" "id.asc"})(with-service-url req service-url-key path)Sets the request URL by resolving a service URL key from the client and
appending path.
service-url-key is a keyword like :auth-url, :storage-url, etc.
The :service field is inferred from the key name.
(-> (request client)
(with-service-url :auth-url "/token"))
Sets the request URL by resolving a service URL key from the client and
appending `path`.
`service-url-key` is a keyword like `:auth-url`, `:storage-url`, etc.
The `:service` field is inferred from the key name.
(-> (request client)
(with-service-url :auth-url "/token"))cljdoc builds & hosts documentation for Clojure/Script libraries
| Ctrl+k | Jump to recent docs |
| ← | Move to previous article |
| → | Move to next article |
| Ctrl+/ | Jump to the search field |