Quick Start
Set up a REST API from a tRPC router in under 5 minutes.
1. Define your router with OpenAPI metadata
Add openapi metadata to any procedure you want exposed as a REST endpoint:
import { initTRPC } from '@trpc/server';
import { z } from 'zod';
import type { OpenApiMeta } from 'trpc-rest';
const t = initTRPC.meta<OpenApiMeta>().create();
export const appRouter = t.router({
getUser: t.procedure
.meta({
openapi: {
method: 'GET',
path: '/users/{id}',
tags: ['Users'],
summary: 'Get a user by ID',
},
})
.input(z.object({ id: z.string() }))
.output(z.object({ id: z.string(), name: z.string() }))
.query(({ input }) => {
return { id: input.id, name: 'Alice' };
}),
createUser: t.procedure
.meta({
openapi: {
method: 'POST',
path: '/users',
tags: ['Users'],
summary: 'Create a user',
},
})
.input(z.object({ name: z.string(), email: z.string() }))
.output(z.object({ id: z.string(), name: z.string() }))
.mutation(({ input }) => {
return { id: 'user-1', name: input.name };
}),
});
export type AppRouter = typeof appRouter;2. Create the REST handler
Wire the handler into your framework's routing. Here's Next.js App Router:
import { createOpenApiFetchHandler } from 'trpc-rest';
import { appRouter } from '@/server/router';
const handler = async (req: Request) => {
return createOpenApiFetchHandler({
router: appRouter,
endpoint: '/api',
req,
createContext: async ({ req }) => {
return {}; // your context factory
},
});
};
export { handler as GET, handler as POST, handler as PUT, handler as PATCH, handler as DELETE };For other frameworks, the pattern is the same — pass any Request object and get a Response back.
3. Generate the OpenAPI spec
import { generateOpenApiDocument } from 'trpc-rest';
import { appRouter } from '@/server/router';
export function GET() {
const doc = generateOpenApiDocument(appRouter, {
title: 'My API',
version: '1.0.0',
baseUrl: 'https://api.example.com',
});
return Response.json(doc);
}Your API is now available at:
GET /api/users/{id}— fetch a userPOST /api/users— create a userGET /api/openapi.json— OpenAPI 3.1.0 spec
4. Test it
# Get a user
curl http://localhost:3000/api/users/alice
# Create a user
curl -X POST http://localhost:3000/api/users \
-H "Content-Type: application/json" \
-d '{"name": "Bob", "email": "bob@example.com"}'
# Fetch the spec
curl http://localhost:3000/api/openapi.json