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

HTTP Requests

Learn how to handle different types of HTTP requests with rest-rpc

const todos = await client.todos.list.fetch({ limit: 10 });
const todo = await client.todos.byId.fetch({ id: "1" });

Request With JSON Body

Regular JSON request bodies are declared with a schema. The body key is flattened for client call and server handler.

export const api = router({
	todos: {
		create: {
			method: "POST",
			path: "/todos",
			body: z.object({
				title: z.string().min(1),
				labels: z.array(z.string()).optional(),
			}),
			response: todoSchema,
		},
	},
});
export const routes = router(api, {
	todos: {
		create({ title, labels }) {
			return createTodo({ title, labels });
		},
	},
});
const todo = await client.todos.create.fetch({
	title: "Write docs",
	labels: ["docs"],
});

Request Without Body

Request without a body can be declared by omitting the body key or by using noBody() explicitly.

import { noBody } from "@rest-rpc/core";

export const api = router({
	todos: {
		list: {
			method: "GET",
			path: "/todos",
			query: z.object({
				limit: z.number().optional(),
			}),
			response: z.array(todoSchema),
		},
		byId: {
			method: "GET",
			path: "/todos/:id",
			body: noBody(),
			response: todoSchema,
		},
	},
});
export const routes = router(api, {
	todos: {
		list({ limit }) {
			return listTodos({ limit });
		},
		byId({ id }) {
			return getTodoById({ id });
		},
	},
});

Request With Custom Content Type

Custom request bodies are declared with customBody(). The body key is not flattened for client call and server handler.

import { customBody, router } from "@rest-rpc/core";

export const api = router({
	imports: {
		csv: {
			method: "POST",
			path: "/imports.csv",
			body: customBody({
				contentType: "text/csv",
				schema: z.string(),
			}),
			response: z.object({
				imported: z.number(),
			}),
		},
	},
});
export const routes = router(api, {
	imports: {
		csv({ body }) {
			return importCsv(body);
		},
	},
});
const result = await client.imports.csv.fetch({
	body: "id,title\n1,Write docs\n",
});

Request With Multiple Custom Content Types

Custom request bodies with multiple content types are declared with customBody() with an array of content types. The body key is not flattened for client call and server handler. It contains both the contentType and the payload.

export const api = router({
	images: {
		upload: {
			method: "POST",
			path: "/images",
			body: customBody({
				contentType: ["image/png", "image/jpeg"],
				schema: z.instanceof(Uint8Array),
			}),
			response: z.object({
				id: z.string(),
			}),
		},
	},
});
export const routes = router(api, {
	images: {
		upload({ body }) {
			return saveImage({
				contentType: body.contentType,
				bytes: body.payload,
			});
		},
	},
});
const image = await client.images.upload.fetch({
	body: {
		contentType: "image/png",
		payload: bytes,
	},
});

Was this page helpful?