Skip to content
rest-rpc
Esc
navigateopen⌘Jpreview
On this page

Schemas

Learn what kind of schemas rest-rpc supports

rest-rpc accepts schemas that implement the Standard Schema spec.

Zod, Valibot, and ArkType are supported Standard Schema libraries. The built-in type<T>() helper provides type-only schemas without runtime validation.

Request Schema Shapes

Request locations are declared with schema records or whole-location schemas.

A schema record maps flattened request keys to individual schemas.

pathParams: {
	id: z.string().uuid(),
},
query: {
	includeCompleted: z.coerce.boolean().optional(),
},
headers: {
	"x-request-id": z.string().optional(),
},
body: {
	title: z.string().min(1),
},

Each record key becomes a key in the client and handler request object.

await client.todos.update.fetch({
	id: "5f4c6e4e-3f7b-46c7-9fb7-a2e41df03695",
	includeCompleted: true,
	"x-request-id": "req_1",
	title: "Ship docs",
});

A whole-location schema validates the whole body, query, or pathParams object as one value.

body: z.object({
	title: z.string().min(1),
	priority: z.enum(["low", "normal", "high"]).default("normal"),
}),

For Zod, Valibot, and ArkType, rest-rpc can resolve flattened request keys from more complex object schemas directly.

body: z.discriminatedUnion("kind", [
	z.object({ kind: z.literal("text"), text: z.string() }),
	z.object({ kind: z.literal("link"), url: z.string().url() }),
]),
query: z.union([
	z.object({ q: z.string() }),
	z.object({ page: z.coerce.number() }),
]),

For other Standard Schema vendors, whole-location schemas need requestKeys or a resolveRequestKeys option so rest-rpc can map flattened keys back to HTTP locations.

body: type<{
	title: string;
}>(),
requestKeys: {
	title: "body",
},

headers is always declared as a schema record.

Schema Input And Output

Schemas have an input type and an output type.

Position Type used
Fetch client request input schema input
Server handler input schema output
Server handler return value schema input
Fetch client response value schema output
WebSocket message send value schema input
WebSocket message receive value schema output

Default HTTP bodies and WebSocket messages travel over JSON. Path params, query params, and headers travel through HTTP strings.

Validation

Server adapters validate incoming request data before calling the handler. The handler receives schema output.

const routes = router(api, {
	todos: {
		get({ id }) {
			return getTodo(id);
		},
	},
});

Server adapters validate handler output before writing the HTTP response. The handler returns schema input.

const api = router({
	todos: {
		get: {
			method: "GET",
			path: "/todos/:id",
			response: todoSchema,
		},
	},
});

Fetch clients do not validate response bodies by default. With validateResponses: true, the client validates HTTP response bodies and incoming WebSocket server messages.

const client = initClient(api, {
	baseUrl: "https://api.example.com",
	validateResponses: true,
});

Was this page helpful?