ESC
Type to search...
S
Soli Docs

HTTP Class

HTTP client class for GET, POST, PUT, PATCH, DELETE requests with JSON support and parallel requests.

HTTP Class

All HTTP functions are accessed via the HTTP class:

response = HTTP.get("https://api.example.com/users")
response = HTTP.post("https://api.example.com/users", { "name": "Alice" })
response = HTTP.request("DELETE", "https://api.example.com/users/1")

SSRF blocklist & redirects

Every URL passed to HTTP.* is validated up-front: schemes other than http/https are rejected, as are hosts that resolve to loopback / private / link-local IP ranges. A request to http://169.254.169.254/... (cloud metadata) or http://10.0.0.1/ fails immediately.

Auto-redirects are not followed by the synchronous HTTP.get / HTTP.post / HTTP.request paths — a 3xx response is returned as-is so a redirect-controlled Location cannot bypass the blocklist. Asynchronous and Model-driven HTTP (the reqwest-backed paths) follow redirects with a custom policy that re-runs the SSRF check on every hop.

Apps that need to follow a 3xx from HTTP.get should inspect response["status"] and response["headers"]["location"] and re-issue the request manually.

Basic HTTP Requests

HTTP.get(url, options?)

Perform an HTTP GET request. Returns a Future that resolves to the response body as a string.

resp = HTTP.get("https://api.example.com/users")
if resp["status"] == 200
  println(resp["body"])
end
HTTP.post(url, body, options?)

Perform an HTTP POST request with a body.

resp = HTTP.post(
  "https://api.example.com/users",
  "name=Alice",
  { "headers": { "Content-Type": "application/x-www-form-urlencoded" } }
)
HTTP.put(url, body, options?)

Perform an HTTP PUT request with a body.

resp = HTTP.put(
  "https://api.example.com/users/1",
  { "name": "Alice Updated" }
)
HTTP.delete(url, options?)

Perform an HTTP DELETE request.

resp = HTTP.delete("https://api.example.com/users/1")
HTTP.patch(url, body, options?)

Perform an HTTP PATCH request with a body.

resp = HTTP.patch(
  "https://api.example.com/users/1",
  { "email": "[email protected]" }
)
HTTP.head(url, options?)

Perform an HTTP HEAD request.

resp = HTTP.head("https://api.example.com/users")
println(resp["headers"])

JSON HTTP Methods

HTTP.get_json(url)

GET request with automatic JSON parsing of response body.

data = HTTP.get_json("https://api.example.com/users/1")
println(data["body"]["name"])
HTTP.post_json(url, data)

POST request with automatic JSON serialization.

resp = HTTP.post_json(
  "https://api.example.com/users",
  { "name": "Alice", "email": "[email protected]" }
)
HTTP.put_json(url, data)

PUT request with automatic JSON serialization.

resp = HTTP.put_json(
  "https://api.example.com/users/1",
  { "name": "Alice Updated", "email": "[email protected]" }
)
HTTP.patch_json(url, data)

PATCH request with automatic JSON serialization.

resp = HTTP.patch_json(
  "https://api.example.com/users/1",
  { "email": "[email protected]" }
)

Generic HTTP Request

HTTP.request(method, url, options?)

Perform any HTTP method (GET, POST, PUT, PATCH, DELETE, etc.).

resp = HTTP.request("DELETE", "https://api.example.com/users/1")
resp = HTTP.request("PATCH", url, { "body": json, "headers": headers })

Status Code Helpers

http_ok(resp)

Check if status is exactly 200

http_success(resp)

Check if status is 2xx

http_redirect(resp)

Check if status is 3xx

http_client_error(resp)

Check if status is 4xx

http_server_error(resp)

Check if status is 5xx

JSON Helpers

HTTP.json_parse(string)

Parse a JSON string into a Soli value

HTTP.json_stringify(value)

Convert a Soli value to a JSON string

Parallel Requests

HTTP.get_all(urls)

Execute multiple GET requests in parallel. Returns response bodies as strings; failed requests appear as {"error": ...} hashes.

responses = HTTP.get_all([
  "https://api.example.com/users",
  "https://api.example.com/posts"
])
HTTP.get_all_json(urls)

Execute multiple GET requests in parallel and parse each body as JSON. Failed requests, non-2xx responses, or unparseable bodies appear as {"error": ...} hashes.

responses = HTTP.get_all_json([
  "https://api.example.com/users.json",
  "https://api.example.com/posts.json"
])

users = responses[0]
if users.has_key("error") {
  print("users failed: " + users["error"])
}
HTTP.parallel(requests)

Execute multiple requests of different methods in parallel.

responses = HTTP.parallel([
  { "method": "GET", "url": "https://api.example.com/users" },
  { "method": "POST", "url": "https://api.example.com/logs", "body": "{}" }
])