HTTP
The HTTP module provides a complete HTTP client for making web requests. It supports all standard HTTP methods, custom headers, Bearer token authentication, and automatic retry with exponential backoff.
HTTP client helpers require TCPConnectAuth, TCPAuth,
NetAuth, or RootAuth in scope. HTTP server helpers require
TCPListenAuth, TCPAuth, NetAuth, or RootAuth.
Basic Requests
match HTTP.get "https://api.example.com/users"
| Ok response -> println response.body
| Err e -> println "Error: ${e}"
body = "{\"name\": \"Alice\", \"email\": \"alice@example.com\"}"
match HTTP.post "https://api.example.com/users" body
| Ok response -> println "Created: ${response.body}"
| Err e -> println "Error: ${e}"
HTTP.put "https://api.example.com/users/1" "{\"name\": \"Bob\"}"
HTTP.delete "https://api.example.com/users/1"
HTTP.patch "https://api.example.com/users/1" "{\"status\": \"active\"}"
HTTP.head "https://api.example.com/users"
Convenience Functions
For quick scripts where you want to panic on errors, use the bang variants:
body = HTTP.get! "https://api.example.com/data"
println body
response = HTTP.post! "https://api.example.com/data" "{\"key\": \"value\"}"
println response.body
Custom Headers
headers = {
"Authorization": "Bearer my-token",
"Content-Type": "application/json"
}
match HTTP.get-with-headers "https://api.example.com/protected" headers
| Ok response -> println response.body
| Err e -> println "Error: ${e}"
match HTTP.post-with-headers "https://api.example.com/data" body headers
| Ok response -> println response.body
| Err e -> println "Error: ${e}"
Bearer Authentication
Convenience functions for Bearer token authentication, commonly used with OAuth2 and API tokens.
auth-header = HTTP.bearer-auth "my-token"
# Returns: "Bearer my-token"
# Use with custom headers
headers = {authorization: auth-header, "X-Custom": "value"}
HTTP.get-with-headers url headers
api-token = "my-secret-token"
match HTTP.get-with-bearer "https://api.example.com/protected" api-token
| Ok response -> println response.body
| Err e -> println "Error: ${e}"
body = "{\"data\": \"value\"}"
match HTTP.post-with-bearer "https://api.example.com/data" body api-token
| Ok response -> println response.body
| Err e -> println "Error: ${e}"
match HTTP.parse-bearer-token "Bearer abc123"
| Some token -> println "Token: ${token}"
| None -> println "No bearer token found"
# Returns None for non-Bearer auth or empty tokens
HTTP.parse-bearer-token "Basic xyz" # None
HTTP.parse-bearer-token "Bearer " # None (empty token)
Retry Support
options = {
method: "GET",
retry: {
max-retries: 3,
backoff: "exponential",
base-delay-ms: 100
}
}
match HTTP.fetch-with-retry "https://api.example.com/data" options
| Ok response -> println response.body
| Err e -> println "Failed after retries: ${e}"
Response Helpers
Convenience functions for checking HTTP response status codes.
true if the response was successful (2xx status code).
true if the response was a redirect (3xx status code).
true if the response was a client error (4xx status code).
true if the response was a server error (5xx status code).
match HTTP.get "https://api.example.com/data"
| Ok response ->
if HTTP.success? response then
println "Success: ${response.body}"
else if HTTP.redirect? response then
println "Redirect (${response.status})"
else if HTTP.client-error? response then
println "Client error (${response.status})"
else if HTTP.server-error? response then
println "Server error (${response.status})"
else
println "Unknown status: ${response.status}"
| Err e -> println "Error: ${e}"
Error Types
All HTTP functions return Result with HTTPError for typed error handling.
type HTTPError =
| HTTPConnectionError { message: String }
| HTTPTimeoutError { message: String }
| HTTPRequestError { message: String }
| HTTPResponseError { message: String }
Handling Errors
match HTTP.get "https://api.example.com/users"
| Ok response -> println response.body
| Err (HTTPConnectionError { message }) ->
println "Connection failed: ${message}"
| Err (HTTPTimeoutError { message }) ->
println "Request timed out: ${message}"
| Err (HTTPRequestError { message }) ->
println "Request error: ${message}"
| Err (HTTPResponseError { message }) ->
println "Response error: ${message}"
# Or use the Error trait for generic handling
match HTTP.get "https://api.example.com/users"
| Ok response -> println response.body
| Err e -> println "Error (${Error.kind e}): ${Error.message e}"