Skip to main content

HTTP Requests

Reqon provides powerful HTTP request handling with built-in support for pagination, retries, rate limiting, and more.

Request methods

// GET - Retrieve data
get "/users"

// POST - Create data
post "/users" { body: { name: "John" } }

// PUT - Replace data
put "/users/123" { body: { name: "Jane" } }

// PATCH - Partial update
patch "/users/123" { body: { email: "jane@example.com" } }

// DELETE - Remove data
delete "/users/123"

Request options

Query parameters

Add query parameters to requests:

get "/users" {
params: {
limit: 100,
offset: 0,
status: "active",
sort: "created_at",
order: "desc"
}
}

Generates: GET /users?limit=100&offset=0&status=active&sort=created_at&order=desc

Dynamic parameters

Use expressions in parameters:

get "/users" {
params: {
since: formatDate(lastSync, "YYYY-MM-DD"),
limit: env("PAGE_SIZE") or 100
}
}

Request body

Send JSON body with POST/PUT/PATCH:

post "/users" {
body: {
name: "John Doe",
email: "john@example.com",
metadata: {
source: "api",
importedAt: now()
}
}
}

Dynamic body

Build body from variables:

for user in usersToCreate {
post "/users" {
body: {
name: user.name,
email: user.email,
role: user.role or "user"
}
}
}

Custom headers

Override or add headers:

get "/data" {
headers: {
"Accept": "application/json",
"X-API-Version": "2.0",
"X-Request-ID": uuid()
}
}

Response handling

Accessing response data

The response variable contains the parsed JSON:

action FetchUsers {
get "/users"

// Access response data
for user in response.data {
store user -> users { key: .id }
}

// Access metadata
validate {
assume response.total > 0
}
}

Response structure

// Common API response pattern
{
"data": [...],
"meta": {
"total": 100,
"page": 1,
"perPage": 20
}
}

// Access in Reqon
for item in response.data { }
validate { assume response.meta.total > 0 }

Working with multiple sources

Default source

The first defined source is the default:

mission Example {
source API { auth: bearer, base: "https://api.example.com" }

action Fetch {
get "/users" // Uses API source
}
}

Named source

Specify source explicitly:

mission MultiSource {
source Primary { auth: bearer, base: "https://primary.api.com" }
source Backup { auth: bearer, base: "https://backup.api.com" }

action FetchFromBoth {
get Primary "/users"
store response -> primaryUsers { key: .id }

get Backup "/users"
store response -> backupUsers { key: .id }
}
}

Dynamic URLs

Build URLs dynamically:

action FetchDetails {
for user in users {
// String concatenation
get concat("/users/", user.id)

// Nested resources
get concat("/users/", user.id, "/orders")

// Complex paths
get concat("/api/v", env("API_VERSION"), "/users/", user.id)
}
}

Request timeouts

Configure at source level:

source SlowAPI {
auth: bearer,
base: "https://slow.api.com",
timeout: 60000 // 60 seconds
}

Or per-request (future feature):

get "/slow-endpoint" {
timeout: 120000 // 2 minutes
}

Error handling

Handle HTTP errors with match:

action SafeFetch {
get "/users"

match response {
{ error: _, code: 401 } -> jump RefreshAuth then retry,
{ error: _, code: 404 } -> skip,
{ error: _, code: 429 } -> retry { delay: 60000 },
{ error: e } -> abort e,
_ -> store response -> users { key: .id }
}
}

Request chaining

Chain requests with data from previous responses:

action FetchWithDetails {
// First request
get "/orders"

for order in response.orders {
// Use data from first request
get concat("/customers/", order.customerId)

map order -> EnrichedOrder {
...order,
customer: response
}

store order -> enrichedOrders { key: .id }
}
}

Batching requests

For APIs that support batch operations:

action BatchFetch {
// Collect IDs
get "/items" { params: { status: "pending" } }

// Batch request
post "/items/batch" {
body: {
ids: response.items.map(.id)
}
}

store response -> batchResults
}

Best practices

Use descriptive error handling

match response {
{ error: _, code: 400 } -> abort "Invalid request data",
{ error: _, code: 401 } -> abort "Authentication failed",
{ error: _, code: 403 } -> abort "Permission denied",
{ error: _, code: 404 } -> abort "Resource not found",
{ error: _, code: 429 } -> retry { delay: 60000 },
{ error: _, code: 500 } -> retry { maxAttempts: 3 },
{ error: e } -> abort e,
_ -> continue
}

Validate before processing

get "/data"

validate response {
assume .data is array,
assume length(.data) > 0
}

for item in response.data { }

Log important requests

get "/important-operation"

match response {
{ success: true } -> {
store { operation: "fetch", status: "success", timestamp: now() } -> logs
continue
},
_ -> {
store { operation: "fetch", status: "failed", response: response } -> logs
abort "Operation failed"
}
}