TRPC Zod Procedure Input Validation
Define typed RPC procedures with tRPC and Zod input schemas, sharing inferred types end to end without a schema registry or codegen step.
Code
import { initTRPC } from '@trpc/server';
import { z } from 'zod';
import { createHTTPContext } from './context';
const t = initTRPC.context<typeof createHTTPContext>().create();
const publicProcedure = t.procedure;
const router = t.router;
const postRouter = router({
byId: publicProcedure
.input(z.object({ id: z.string().uuid() }))
.query(async ({ input, ctx }) => {
return ctx.db.posts.find((p) => p.id === input.id) ?? null;
}),
list: publicProcedure
.input(z.object({
page: z.number().int().min(1).default(1),
limit: z.number().int().min(1).max(50).default(20),
}))
.query(async ({ input, ctx }) => {
const start = (input.page - 1) * input.limit;
return ctx.db.posts.slice(start, start + input.limit);
}),
create: publicProcedure
.input(z.object({
title: z.string().min(3).max(120),
body: z.string().min(1),
}))
.mutation(async ({ input, ctx }) => {
const post = { id: crypto.randomUUID(), ...input };
ctx.db.posts.push(post);
return post;
}),
});
export const appRouter = router({ posts: postRouter });
export type AppRouter = typeof appRouter;Report a problem with this exampleOpens a pre-filled issue on GitHub.