Documentation
API

Define oRPC Router

Expose service methods as public or authorized API routes.

Create:

src/features/web/todo/api/todo.router.ts

Routes 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/list

Register in the root router

Add your router to:

src/lib/orpc/router.ts
import { todoRouter } from '@/features/web/todo/api/todo.router';

export const router = {
  todo: todoRouter,
};

On this page