tRPC Advanced mit Claude Code: End-to-End Typsicherheit 2026
tRPC eliminiert die API-Schicht — vollständige TypeScript-Typsicherheit vom Server bis zum Client ohne Codegen. Claude Code kennt alle Patterns: Router-Komposition, Middleware, Subscriptions und React Query Integration.
Router-Architektur und Komposition
RouterModulare Router-Struktur
# Prompt: "Erstelle tRPC v11 Router-Architektur für eine SaaS-App"
// server/trpc.ts — Basis-Setup
import { initTRPC, TRPCError } from '@trpc/server';
import { ZodError } from 'zod';
import superjson from 'superjson';
export const t = initTRPC.context<Context>().create({
transformer: superjson, // Date, Map, Set nativ übertragen
errorFormatter({ shape, error }) {
return {
...shape,
data: {
...shape.data,
zodError: error.cause instanceof ZodError
? error.cause.flatten()
: null,
},
};
},
});
export const router = t.router;
export const publicProcedure = t.procedure;
export const protectedProcedure = t.procedure.use(isAuthenticated);
// server/routers/user.ts
export const userRouter = router({
me: protectedProcedure.query(async ({ ctx }) => {
return ctx.db.user.findUnique({ where: { id: ctx.session.userId } });
}),
update: protectedProcedure
.input(z.object({
name: z.string().min(1).max(100),
bio: z.string().max(500).optional(),
}))
.mutation(async ({ ctx, input }) => {
return ctx.db.user.update({
where: { id: ctx.session.userId },
data: input,
});
}),
});
// server/root.ts — Alle Router zusammenführen
export const appRouter = router({
user: userRouter,
project: projectRouter,
billing: billingRouter,
});
export type AppRouter = typeof appRouter;
Middleware: Auth, Logging, Rate-Limiting
MiddlewareChainbare Middleware-Pipes
# Prompt: "Auth-Middleware, Logging und Rate-Limiting für tRPC"
// Authentifizierung
const isAuthenticated = t.middleware(async ({ ctx, next }) => {
if (!ctx.session?.userId) {
throw new TRPCError({ code: 'UNAUTHORIZED' });
}
return next({ ctx: { ...ctx, userId: ctx.session.userId } });
});
// Logging Middleware
const withLogging = t.middleware(async ({ path, type, next }) => {
const start = Date.now();
const result = await next();
console.log(`[tRPC] ${type} ${path} — ${Date.now() - start}ms`);
return result;
});
// Rate-Limiting (mit Upstash Redis)
const withRateLimit = t.middleware(async ({ ctx, next }) => {
const { success } = await ratelimit.limit(ctx.ip ?? 'anonymous');
if (!success) {
throw new TRPCError({
code: 'TOO_MANY_REQUESTS',
message: 'Rate limit überschritten. Bitte warte 1 Minute.',
});
}
return next();
});
// Kombinieren: Middleware-Pipes
export const protectedProcedure = t.procedure
.use(withLogging)
.use(withRateLimit)
.use(isAuthenticated);
// Reihenfolge: withLogging → withRateLimit → isAuthenticated → Handler
Middleware-Tipp: "Füge Middleware hinzu die [Feature X] implementiert. Die Middleware soll chainbar sein und TypeScript-Context korrekt erweitern." Claude Code versteht tRPC's ctx-Typ-Erweiterungsmuster perfekt.
React Query Integration im Client
ClientTypsichere Queries und Mutations
# Prompt: "tRPC Client mit optimistischen Updates und Invalidierung"
// utils/trpc.ts
import { createTRPCReact } from '@trpc/react-query';
import type { AppRouter } from '../server/root';
export const trpc = createTRPCReact<AppRouter>();
// In React-Komponenten — vollständige Typsicherheit!
function ProjectList() {
const utils = trpc.useUtils();
// Query: auto-complete für .project.list mit Typen
const { data: projects } = trpc.project.list.useQuery(
{ orgId: currentOrgId },
{ staleTime: 60_000 }
);
// Mutation mit optimistischem Update
const createProject = trpc.project.create.useMutation({
onMutate: async (newProject) => {
await utils.project.list.cancel();
const prev = utils.project.list.getData({ orgId: currentOrgId });
utils.project.list.setData({ orgId: currentOrgId }, (old) => [
...old ?? [],
{ ...newProject, id: 'temp-id', createdAt: new Date() }
]);
return { prev };
},
onError: (err, _, ctx) => {
// Rollback bei Fehler
utils.project.list.setData({ orgId: currentOrgId }, ctx?.prev);
},
onSettled: () => {
// Nach erfolg: echte Daten laden
utils.project.list.invalidate();
},
});
}
Subscriptions: Real-time mit WebSockets
SubscriptionsLive-Updates ohne Polling
# Prompt: "tRPC Subscription für Live-Benachrichtigungen"
// Server: EventEmitter-basierte Subscription
import { observable } from '@trpc/server/observable';
import { EventEmitter } from 'events';
const ee = new EventEmitter();
export const notificationRouter = router({
onNew: protectedProcedure.subscription(({ ctx }) => {
return observable<Notification>((emit) => {
const handler = (notification: Notification) => {
if (notification.userId === ctx.userId) {
emit.next(notification);
}
};
ee.on('notification', handler);
return () => ee.off('notification', handler);
});
}),
});
// Trigger von überall:
export function sendNotification(notification: Notification) {
ee.emit('notification', notification);
}
// Client:
trpc.notification.onNew.useSubscription(undefined, {
onData: (notification) => {
toast(notification.message);
utils.notification.list.invalidate();
},
});
Subscriptions erfordern
@trpc/server/adapters/ws und einen separaten WebSocket-Server-Port. Claude Code generiert die vollständige WebSocket-Adapter-Konfiguration für Next.js (Custom Server) und standalone Node.js.OpenAPI Export: REST aus tRPC
# trpc-openapi: REST-Endpunkte aus tRPC generieren
import { generateOpenApiDocument } from 'trpc-openapi';
// Procedure mit OpenAPI-Metadaten
export const projectRouter = router({
list: publicProcedure
.meta({ openapi: { method: 'GET', path: '/projects', tags: ['projects'] } })
.input(z.object({ orgId: z.string() }))
.output(z.array(ProjectSchema))
.query(async ({ input }) => getProjects(input.orgId)),
create: protectedProcedure
.meta({ openapi: { method: 'POST', path: '/projects', tags: ['projects'] } })
.input(CreateProjectSchema)
.output(ProjectSchema)
.mutation(async ({ ctx, input }) => createProject(ctx.userId, input)),
});
// OpenAPI-Dokument generieren:
const openApiDocument = generateOpenApiDocument(appRouter, {
title: 'My SaaS API',
version: '1.0.0',
baseUrl: 'https://api.myapp.com',
});
// Ergebnis: Swagger/OpenAPI 3.0 kompatibles JSON
API-Entwicklung im Kurs
Im Claude Code Mastery Kurs: vollständiges tRPC-Modul mit Router-Architektur, Middleware-Chains, React Query Integration, Subscriptions und OpenAPI-Export — inkl. Production-Deployment auf Next.js und standalone Node.js.
14 Tage kostenlos testen →