Next.js
Register contract routes in Next.js App Router route handlers.
Use @rest-rpc/next to create route handlers for Next.js App Router.
Install
pnpm add @rest-rpc/core @rest-rpc/next
Single Route Handler
Contract path: /api/todos/:id
App router route: app/api/todos/[id]/route.ts
import { createRouteHandler } from "@rest-rpc/next";
import { api } from "@/contract";
export const { GET } = createRouteHandler(api.todos.get, ({ id, context }) => {
const userAgent = context.request.headers.get("user-agent");
void userAgent;
const todo = todos.get(id);
if (!todo) {
return {
status: 404,
body: {
code: "TODO_NOT_FOUND",
},
};
}
return todo;
});
Handlers receive flattened request input where context.request contains the
native Request.
get({ id, context }) {
return loadTodo({
id,
authorization: context.request.headers.get("authorization"),
});
}
Catch-all Routes
Contract path: /api/*
App router route: app/api/[...rest]/route.ts
import { createRouterHandler } from "@rest-rpc/next";
import { api } from "@/contract";
export const { GET, POST } = createRouterHandler(api, {
todos: {
list: async ({ context }) => {
const userAgent = context.request.headers.get("user-agent");
void userAgent;
return todos.list();
},
create: async ({ title }) => {
const todo = await todos.create({ title });
return {
status: 201,
body: todo,
};
},
},
});
With a catch-all route, @rest-rpc/next owns path matching inside that route
module. Requests that do not match the contract return 404.
Next route handlers use module exports such as runtime, dynamic, and
revalidate to define route-level behavior. With a catch-all route, those
settings apply to every contract route mounted under that file.
Error Handling
Use errorHandlers to customize server-generated error responses. Declared
responses returned from handlers, including ContractResponseError, do not run
through these hooks.
export const { GET, POST } = createRouterHandler(api, handlers, {
errorHandlers: {
onRequestValidationError: ({ issues }) => ({
status: 422,
body: { code: "VALIDATION_ERROR", issues },
}),
onUnhandledError: () => ({
status: 500,
body: { code: "INTERNAL_SERVER_ERROR" },
}),
},
});
WebSocket Support
Websocket routes are not supported in Next.js route handlers because Next does not itself support WebSocket connections. If you need WebSocket support, use a different server adapter that supports WebSockets.