API
Define oRPC Router
Expose service methods as public or authorized API routes.
Create:
src/features/web/todo/api/todo.router.tsRoutes can be:
- Public with
base - Authorized with
authorized
Copy-paste scaffold
import { ORPCError } from '@orpc/server';
import { z } from 'zod';
import {
CreateTodoInputSchema,
DeleteTodoInputSchema,
ListTodosOutputSchema,
TodoSchema,
UpdateTodoInputSchema,
} from '@/features/web/todo/model/todo.schema';
import {
createTodo,
deleteTodo,
listTodos,
TodoNotFoundError,
updateTodo,
} from '@/features/web/todo/service/todo.service';
import { authorized } from '@/lib/orpc/context/authorized';
import { base } from '@/lib/orpc/context/base';
export const todoRouter = {
list: base
.route({ method: 'GET', path: '/todo/list' })
.output(ListTodosOutputSchema)
.handler(async () => {
return listTodos();
}),
create: authorized
.route({ method: 'POST', path: '/todo/create' })
.input(CreateTodoInputSchema)
.output(TodoSchema)
.handler(async ({ input }) => {
return createTodo(input);
}),
update: authorized
.route({ method: 'PUT', path: '/todo/update' })
.input(UpdateTodoInputSchema)
.output(TodoSchema)
.handler(async ({ input }) => {
try {
return await updateTodo(input);
} catch (error) {
if (error instanceof TodoNotFoundError) {
throw new ORPCError('NOT_FOUND', {
message: 'Todo not found',
});
}
throw error;
}
}),
delete: authorized
.route({ method: 'DELETE', path: '/todo/delete' })
.input(DeleteTodoInputSchema)
.output(z.object({ id: z.string() }))
.handler(async ({ input }) => {
try {
return await deleteTodo(input);
} catch (error) {
if (error instanceof TodoNotFoundError) {
throw new ORPCError('NOT_FOUND', {
message: 'Todo not found',
});
}
throw error;
}
}),
};When this router is registered in src/lib/orpc/router.ts, each path is available under /api/v1.
Example:
/api/v1/todo/listRegister in the root router
Add your router to:
src/lib/orpc/router.tsimport { todoRouter } from '@/features/web/todo/api/todo.router';
export const router = {
todo: todoRouter,
};