HTTP(S)
HTTP client generator creates type-safe functions for making HTTP requests based on your API specification. It supports various authentication methods, retry logic, and extensibility hooks.
It is currently available through the generators (channels):
This is available through AsyncAPI (requires the HTTP method binding for operations and statusCode for messages) and directly from OpenAPI documents (see From OpenAPI below).
TypeScript
| Feature | Is supported? |
|---|---|
| Download | ❌ |
| Upload | ❌ |
| Retry with backoff | ✅ |
| OAuth2 Authorization code | ❌ (browser-only) |
| OAuth2 Implicit | ❌ (browser-only) |
| OAuth2 Password | ✅ |
| OAuth2 Client Credentials | ✅ |
| OAuth2 Token Refresh | ✅ |
| Username/password Authentication | ✅ |
| Bearer Authentication | ✅ |
| Basic Authentication | ✅ |
| API Key Authentication | ✅ |
| Request/Response Hooks | ✅ |
| XML Based API | ❌ |
| JSON Based API | ✅ |
| POST | ✅ |
| GET | ✅ |
| PATCH | ✅ |
| DELETE | ✅ |
| PUT | ✅ |
| HEAD | ✅ |
| OPTIONS | ✅ |
Channels
Read more about the channels generator here.
| Input (AsyncAPI) | Using the code |
|---|---|
| |
From OpenAPI
The http_client protocol is also generated directly from an OpenAPI document (2.0/3.0/3.1). Each path + method becomes one function. Configure the channels generator with inputType: 'openapi' and protocols: ['http_client'].
Function names come from each operation's operationId (camel-cased). When an operation has no operationId, a name is synthesized from the method and path, e.g. GET /v2/connect/{referenceId} → getV2ConnectReferenceId. Give your operations operationIds for the cleanest client.
As a consumer you work with three generated pieces: the call functions (http_client.ts), the request/response body models (payload/), and the path/query parameter models (parameter/):
import { http_client } from './__gen__/channels';
import { PostV2ConnectRequest } from './__gen__/channels/payload/PostV2ConnectRequest';
import { GetV2ConnectReferenceIdParameters } from './__gen__/channels/parameter/GetV2ConnectReferenceIdParameters';
// Request with a body: build the model, pass it as `payload`.
const created = await http_client.postV2Connect({
baseUrl: 'https://api.example.com',
payload: new PostV2ConnectRequest({ returnUrl: 'https://shop.example/return' })
});
console.log(created.data.connectUrl); // typed response model
// Request with a path parameter: supply it through the parameter model.
const connect = await http_client.getV2ConnectReferenceId({
baseUrl: 'https://api.example.com',
parameters: new GetV2ConnectReferenceIdParameters({ referenceId: 'ref_123' })
});
console.log(connect.data.safepayAccountId);
See the runnable openapi-http-client example for a complete, self-contained setup.
Authentication
The HTTP client uses a discriminated union for authentication, providing excellent TypeScript autocomplete support.
Bearer Token
const response = await postPingPostRequest({
payload: message,
baseUrl: 'https://api.example.com',
auth: {
type: 'bearer',
token: 'your-jwt-token'
}
});
Basic Authentication
const response = await postPingPostRequest({
payload: message,
baseUrl: 'https://api.example.com',
auth: {
type: 'basic',
username: 'user',
password: 'pass'
}
});
API Key
// API Key in header (default)
const response = await postPingPostRequest({
payload: message,
baseUrl: 'https://api.example.com',
auth: {
type: 'apiKey',
key: 'your-api-key',
name: 'X-API-Key', // Header name (default: 'X-API-Key')
in: 'header' // 'header' or 'query'
}
});
// API Key in query parameter
const response = await postPingPostRequest({
payload: message,
baseUrl: 'https://api.example.com',
auth: {
type: 'apiKey',
key: 'your-api-key',
name: 'api_key',
in: 'query'
}
});
OAuth2 Client Credentials
For server-to-server authentication:
const response = await postPingPostRequest({
payload: message,
baseUrl: 'https://api.example.com',
auth: {
type: 'oauth2',
flow: 'client_credentials',
clientId: 'your-client-id',
clientSecret: 'your-client-secret',
tokenUrl: 'https://auth.example.com/oauth/token',
scopes: ['read', 'write'],
onTokenRefresh: (tokens) => {
// Called when tokens are obtained/refreshed
console.log('New access token:', tokens.accessToken);
}
}
});
OAuth2 Password Flow
For legacy applications requiring username/password:
const response = await postPingPostRequest({
payload: message,
baseUrl: 'https://api.example.com',
auth: {
type: 'oauth2',
flow: 'password',
clientId: 'your-client-id',
username: 'user@example.com',
password: 'user-password',
tokenUrl: 'https://auth.example.com/oauth/token',
onTokenRefresh: (tokens) => {
// Store tokens for future use
saveTokens(tokens);
}
}
});
OAuth2 with Pre-obtained Token
For tokens obtained via browser-based flows (implicit, authorization code):
// Token obtained from browser OAuth flow
const accessToken = getTokenFromBrowserFlow();
const response = await postPingPostRequest({
payload: message,
baseUrl: 'https://api.example.com',
auth: {
type: 'oauth2',
accessToken: accessToken,
refreshToken: refreshToken, // Optional: for auto-refresh on 401
tokenUrl: 'https://auth.example.com/oauth/token',
clientId: 'your-client-id',
onTokenRefresh: (tokens) => {
// Update stored tokens
updateStoredTokens(tokens);
}
}
});
Retry with Exponential Backoff
Configure automatic retry for failed requests:
const response = await postPingPostRequest({
payload: message,
baseUrl: 'https://api.example.com',
retry: {
maxRetries: 3, // Maximum retry attempts (default: 3)
initialDelayMs: 1000, // Initial delay before first retry (default: 1000)
maxDelayMs: 30000, // Maximum delay between retries (default: 30000)
backoffMultiplier: 2, // Exponential backoff multiplier (default: 2)
retryableStatusCodes: [408, 429, 500, 502, 503, 504], // Status codes to retry
retryOnNetworkError: true, // Retry on network failures
onRetry: (attempt, delay, error) => {
console.log(`Retry attempt ${attempt} after ${delay}ms: ${error.message}`);
}
}
});
Request/Response Hooks
Customize request behavior with hooks:
const response = await postPingPostRequest({
payload: message,
baseUrl: 'https://api.example.com',
hooks: {
// Modify request before sending
beforeRequest: async (params) => {
console.log('Making request to:', params.url);
// Add custom header
return {
...params,
headers: {
...params.headers,
'X-Request-ID': generateRequestId()
}
};
},
// Replace the default fetch implementation
makeRequest: async (params) => {
// Use axios, got, or any HTTP client
const axiosResponse = await axios({
url: params.url,
method: params.method,
headers: params.headers,
data: params.body
});
return {
ok: axiosResponse.status >= 200 && axiosResponse.status < 300,
status: axiosResponse.status,
statusText: axiosResponse.statusText,
headers: axiosResponse.headers,
json: () => axiosResponse.data
};
},
// Process response after receiving
afterResponse: async (response, params) => {
console.log(`Response ${response.status} from ${params.url}`);
return response;
},
// Handle errors
onError: async (error, params) => {
console.error(`Request failed: ${error.message}`);
// Optionally transform the error
return error;
}
}
});
Path Parameters
For operations with path parameters, the generator creates typed parameter classes:
import { UserItemsParameters } from './__gen__/parameters/UserItemsParameters';
// Create parameters with type safety
const params = new UserItemsParameters({
userId: 'user-123',
itemId: 456
});
const response = await getGetUserItem({
baseUrl: 'https://api.example.com',
parameters: params // Replaces {userId} and {itemId} in path
});
Typed Headers
For operations with defined headers, the generator creates typed header classes:
import { ItemRequestHeaders } from './__gen__/headers/ItemRequestHeaders';
const headers = new ItemRequestHeaders({
xCorrelationId: 'corr-123',
xRequestId: 'req-456'
});
const response = await putUpdateUserItem({
baseUrl: 'https://api.example.com',
parameters: params,
payload: itemData,
requestHeaders: headers // Type-safe headers
});
Additional Headers and Query Parameters
Add custom headers or query parameters to any request:
const response = await postPingPostRequest({
payload: message,
baseUrl: 'https://api.example.com',
additionalHeaders: {
'X-Custom-Header': 'value',
'Accept-Language': 'en-US'
},
additionalQueryParams: {
include: 'metadata',
format: 'detailed'
}
});
Multi-Status Responses
For operations that return different payloads based on status code, the generator creates union types:
# AsyncAPI spec with multiple response types
operations:
getItem:
reply:
messages:
- $ref: '#/components/messages/ItemResponse' # 200
- $ref: '#/components/messages/NotFoundError' # 404
const response = await getItemRequest({
baseUrl: 'https://api.example.com',
parameters: params
});
// Response type is union: ItemResponse | NotFoundError
// Use response.status to discriminate
if (response.status === 200) {
console.log('Item:', response.data); // ItemResponse
} else if (response.status === 404) {
console.log('Not found:', response.data); // NotFoundError
}