fetch()
Makes HTTP requests from within a workflow. This is a special step function that wraps the standard fetch API, automatically handling serialization and providing retry semantics.
This is useful when you need to call external APIs or services from within your workflow.
fetch is a special type of step function provided and should be called directly inside workflow functions.
import { fetch } from "workflow"
async function apiWorkflow() {
"use workflow"
// Fetch data from an API
const response = await fetch("https://api.example.com/data")
return await response.json()
}API Signature
Parameters
Accepts the same arguments as web fetch
| Name | Type | Description |
|---|---|---|
args | [input: string | URL | Request, init?: RequestInit | undefined] |
Returns
Returns the same response as web fetch
Promise<Response>Examples
Basic Usage
Here's a simple example of how you can use fetch inside your workflow.
import { fetch } from "workflow"
async function apiWorkflow() {
"use workflow"
// Fetch data from an API
const response = await fetch("https://api.example.com/data")
const data = await response.json()
// Make a POST request
const postResponse = await fetch("https://api.example.com/create", {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({ name: "test" })
})
return data
}We call fetch() with a URL and optional request options, just like the standard fetch API. The workflow runtime automatically handles the response serialization.
This API is provided as a convenience to easily use fetch in workflow, but often, you might want to extend and implement your own fetch for more powerful error handing and retry logic.
Customizing Fetch Behavior
Here's an example of a custom fetch wrapper that provides more sophisticated error handling with custom retry logic:
import { FatalError, RetryableError } from "workflow"
export async function customFetch(
url: string,
init?: RequestInit
) {
"use step"
const response = await fetch(url, init)
// Handle client errors (4xx) - don't retry
if (response.status >= 400 && response.status < 500) {
if (response.status === 429) {
// Rate limited - retry with backoff from Retry-After header
const retryAfter = response.headers.get("Retry-After")
// Use `RetryableError` to customize the retry
throw new RetryableError(
`Rate limited by ${url}`,
{ retryAfter: `${retryAfter} seconds` }
)
}
// Other client errors are fatal (400, 401, 403, 404, etc.)
throw new FatalError(
`Client error ${response.status}: ${response.statusText}`
)
}
// Handle server errors (5xx) - will retry automatically
if (!response.ok) {
throw new Error(
`Server error ${response.status}: ${response.statusText}`
)
}
return response
}This example demonstrates:
- Setting custom
maxRetriesto 5 attempts. - Throwing
FatalErrorfor client errors (400-499) to prevent retries. - Handling 429 rate limiting by reading the
Retry-Afterheader and usingRetryableError. - Allowing automatic retries for server errors (5xx).