TypeScript checks the values you pass to the SDK at compile time, but data from a form, a request or JSON.parse is only checked when you check it. The SDK can validate the calls that run functions and invoke APIs against a schema, before the call is sent and after the answer arrives.
The SDK accepts any Standard Schema, the interface implemented by Zod, Valibot, ArkType and other validation libraries. It does not depend on any of them, so use the one you already have.
Functions
.args() checks the arguments before the call is sent, and .returns() checks the result and types the promise as what the schema produces. The schema for .args() validates the whole array of arguments, so use a tuple.
import { z } from 'zod';
const sum = await db
.run('fn::add', [1, 2])
.args(z.tuple([z.number(), z.number()]))
.returns(z.number());
// sum: numberAPIs
.request() checks the request body before the request is sent, and .response() checks the body of the response.
const User = z.object({ id: z.string(), name: z.string() });
const user = await db
.api()
.post('/users', { name: 'Ada' })
.request(z.object({ name: z.string() }))
.response(User)
.value();
// user: { id: string; name: string }Only the body of a successful response (status 200 to 299) is checked against .response(), because an error response carries a different body. With .value(), an unsuccessful response still throws an UnsuccessfulApiError.
When a value is invalid
The promise rejects with a SchemaValidationError. It lists every issue the schema reported, each with the path of the failing value. When the arguments or the request body are invalid, nothing is sent to the database.
import { SchemaValidationError } from 'surrealdb';
try {
await db.run('fn::add', ['1', 2]).args(z.tuple([z.number(), z.number()]));
} catch (error) {
if (error instanceof SchemaValidationError) {
console.error(error.subject); // "arguments for fn::add"
console.error(error.issues); // [{ message: "...", path: [0] }]
}
}SchemaValidationError is a client-side check. The server reports its own failures with a different ValidationError.
Things to know
A schema which transforms or coerces its input changes what is sent: the SDK sends the value the schema produced, not the one you passed.
Validation runs when the promise is awaited. It does not apply to
.compile()or.stream().With
.json(), a result schema sees the JSON-compatible result, not the SurrealDB value types.Validation is opt-in per call. Calls without a schema behave as before.