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
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).json()Configure the query to return the result as a JSON string.
Method SyntaxapiPromise.json()
ApiPromise<Req, Res, V, true> - Promise returning JSON string
const jsonString = await db.api().get('/users').json(); console.log(typeof jsonString); // 'string'
.header()Append a header to the API request.
Method SyntaxapiPromise.header(name, value)
| Parameter | Type | Description |
|---|---|---|
name required | string | The header name. |
value required | string | The header value. |
ApiPromise<Req, Res, V, J> - Chainable promise
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 SyntaxapiPromise.value()
ApiPromise<Req, Res, true, J> - Promise returning only the value
Without .value()const response = await db.api().get('/users'); console.log(response.body); // The actual data console.log(response.status); // HTTP status console.log(response.headers); // Response headers
With .value()const users = await db.api().get('/users').value(); console.log(users); // Direct access to user array
.value())interface ApiResponse<T> { body?: T; headers?: Record<string, string>; status?: number; }
.value())// Returns Res directly instead of ApiResponse<Res>
import { Surreal } from 'surrealdb'; const db = new Surreal(); await db.connect('ws://localhost:8000'); const api = db.api(); // GET request const users = await api.get('/users').value(); // POST request const newUser = await api.post('/users', { name: 'John Doe', email: 'john@example.com' }).value(); // PUT request const updated = await api.put('/users/123', { name: 'John Smith' }).value(); // DELETE request await api.delete('/users/123').value();
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();
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>(); // Type-safe calls const users: User[] = await api.get('/users').value(); const newUser: User = await api.post('/users', { name: 'Alice', email: 'alice@example.com', password: 'secure' }).value();
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);
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();
// Login const loginResult = await db.api().post('/auth/login', { email: 'user@example.com', password: 'password123' }).value(); const { access_token } = loginResult; // Use token for subsequent requests const api = db.api(); api.header('Authorization', `Bearer ${access_token}`); const profile = await api.get('/profile').value(); const orders = await api.get('/orders').value();
const api = db.api(); // Check if resource exists const checkResponse = await api.get('/users/123'); if (checkResponse.status === 404) { // Create if doesn't exist await api.post('/users/123', userData).value(); } else { // Update if exists await api.put('/users/123', userData).value(); }
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' };
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() );
// Build query params manually const params = new URLSearchParams({ filter: 'active', sort: 'created_at', order: 'desc' }); const users = await db.api().get(`/users?${params}`).value();
// Both use the same connection const db = new Surreal(); await db.connect('ws://localhost:8000'); // Regular query (via WebSocket/HTTP RPC) const users1 = await db.select(new Table('users')); // API endpoint (via defined API routes) const users2 = await db.api().get('/users').value(); // Both work, but API endpoints allow custom logic
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']);
// Good: Type-safe API type MyApi = { "/users": { get: [void, User[]] }; }; const api = db.api<MyApi>(); // Avoid: Untyped const api = db.api();
// Good: Direct value access const users = await api.get('/users').value(); // More verbose: const response = await api.get('/users'); const users = response.body;
// Good: Specific error handling try { const result = await api.get('/users').value(); } catch (error) { if (error instanceof UnsuccessfulApiError) { // Handle API errors } }