ApiPromise<Req, Res, V, J>
The ApiPromise class provides an interface for executing user-defined API endpoint calls. It extends Promise, allowing you to await it directly or configure the response handling.
Returned by: Methods on SurrealApi
Source: query/api.ts
Type Parameters
Req - The request body typeRes - The response body typeV - Boolean for value-only response (default: false)J - Boolean indicating if result is JSON (default: false)
Configuration Methods
.json()
Configure the query to return the result as a JSON string.
Method Syntax
apiPromise.json()
Returns
ApiPromise<Req, Res, V, true> - Promise returning JSON string
Example
const jsonString = await db.api().get('/users').json();
console.log(typeof jsonString);
Append a header to the API request.
Method Syntax
apiPromise.header(name, value)
Parameters
| Parameter | Type | Description |
|---|
name required | string | The header name. |
value required | string | The header value. |
Returns
ApiPromise<Req, Res, V, J> - Chainable promise
Example
const result = await db.api().get('/users')
.header('X-Custom-Header', 'value')
.header('Authorization', 'Bearer token');
.value()
Return only the response body value, without the wrapper object.
Method Syntax
apiPromise.value()
Returns
ApiPromise<Req, Res, true, J> - Promise returning only the value
Examples
Without .value()
const response = await db.api().get('/users');
console.log(response.body);
console.log(response.status);
console.log(response.headers);
With .value()
const users = await db.api().get('/users').value();
console.log(users);
Response Structure
Default Response (without .value())
interface ApiResponse<T> {
body?: T;
headers?: Record<string, string>;
status?: number;
}
Value Response (with .value())
Complete Examples
Basic API Calls
import { Surreal } from 'surrealdb';
const db = new Surreal();
await db.connect('ws://localhost:8000');
const api = db.api();
const users = await api.get('/users').value();
const newUser = await api.post('/users', {
name: 'John Doe',
email: 'john@example.com'
}).value();
const updated = await api.put('/users/123', {
name: 'John Smith'
}).value();
await api.delete('/users/123').value();
With Full Response
const response = await db.api().get('/users');
console.log('Status:', response.status);
console.log('Headers:', response.headers);
console.log('Body:', response.body);
if (response.status === 200) {
console.log('Success:', response.body);
}
const result = await db.api().post('/protected', data)
.header('Authorization', `Bearer ${token}`)
.header('X-API-Version', '2.0')
.value();
Type-Safe API Calls
interface User {
id: string;
name: string;
email: string;
}
interface CreateUserRequest {
name: string;
email: string;
password: string;
}
type ApiPaths = {
"/users": {
get: [void, User[]];
post: [CreateUserRequest, User];
};
};
const api = db.api<ApiPaths>();
const users: User[] = await api.get('/users').value();
const newUser: User = await api.post('/users', {
name: 'Alice',
email: 'alice@example.com',
password: 'secure'
}).value();
Error Handling
try {
const user = await db.api().get('/users/999').value();
} catch (error) {
if (error instanceof UnsuccessfulApiError) {
console.error('API error:', error.response);
console.error('Status:', error.response.status);
console.error('Message:', error.response.body);
}
}
async function fetchPage(page: number, pageSize: number) {
return db.api().get(`/users?page=${page}&limit=${pageSize}`).value();
}
const page1 = await fetchPage(1, 20);
const page2 = await fetchPage(2, 20);
File Upload
const formData = new FormData();
formData.append('file', fileBlob);
formData.append('name', 'profile-picture');
const result = await db.api().post('/upload', formData)
.header('Content-Type', 'multipart/form-data')
.value();
Authentication Flow
const loginResult = await db.api().post('/auth/login', {
email: 'user@example.com',
password: 'password123'
}).value();
const { access_token } = loginResult;
const api = db.api();
api.header('Authorization', `Bearer ${access_token}`);
const profile = await api.get('/profile').value();
const orders = await api.get('/orders').value();
Conditional Requests
const api = db.api();
const checkResponse = await api.get('/users/123');
if (checkResponse.status === 404) {
await api.post('/users/123', userData).value();
} else {
await api.put('/users/123', userData).value();
}
Batch Operations
const api = db.api();
const promises = userIds.map(id =>
api.get(`/users/${id}`).value()
);
const users = await Promise.all(promises);
console.log(`Fetched ${users.length} users`);
const response = await db.api().get('/users');
const transformed = {
data: response.body,
timestamp: new Date(),
status: response.status,
cached: response.headers?.['X-Cache'] === 'HIT'
};
Retry Pattern
async function apiWithRetry(
apiCall: () => Promise<any>,
maxRetries = 3
) {
for (let i = 0; i < maxRetries; i++) {
try {
return await apiCall();
} catch (error) {
if (i === maxRetries - 1) throw error;
await new Promise(r => setTimeout(r, 1000 * (i + 1)));
}
}
}
const result = await apiWithRetry(() =>
db.api().get('/unstable-endpoint').value()
);
Query Parameters
const params = new URLSearchParams({
filter: 'active',
sort: 'created_at',
order: 'desc'
});
const users = await db.api().get(`/users?${params}`).value();
WebSocket vs API Endpoints
const db = new Surreal();
await db.connect('ws://localhost:8000');
const users1 = await db.select(new Table('users'));
const users2 = await db.api().get('/users').value();
const response = await db.api().get('/users');
console.log('Content-Type:', response.headers?.['Content-Type']);
console.log('Cache-Control:', response.headers?.['Cache-Control']);
console.log('X-Custom:', response.headers?.['X-Custom-Header']);
Best Practices
1. Use Type Definitions
type MyApi = {
"/users": { get: [void, User[]] };
};
const api = db.api<MyApi>();
const api = db.api();
2. Use .value() for Simpler Code
const users = await api.get('/users').value();
const response = await api.get('/users');
const users = response.body;
3. Handle Errors Gracefully
try {
const result = await api.get('/users').value();
} catch (error) {
if (error instanceof UnsuccessfulApiError) {
}
}
See Also