Hoppa till huvudinnehållet
Version: 11.x

Fastify-adaptern

Inofficiell Beta-översättning

Denna sida har översatts av PageTurner AI (beta). Inte officiellt godkänd av projektet. Hittade du ett fel? Rapportera problem →

Exempelapp

Det bästa sättet att komma igång med Fastify-adaptern är att titta på exempelapplikationen.

DescriptionLinks
  • Fastify server with WebSocket
  • Simple tRPC client in node

Så här använder du tRPC med Fastify

Installera beroenden

bash
yarn add @trpc/server fastify zod
bash
yarn add @trpc/server fastify zod

⚠️ Krav på Fastify-version

tRPC v11:s Fastify-adapter kräver Fastify v5 eller senare.
Om du använder Fastify v4 kan förfrågningar returnera tomma svar utan felmeddelanden.

Zod är inte ett obligatoriskt beroende, men det används i exempelroutern nedan.

Skapa routern

Först och främst behöver du en router för att hantera dina queries, mutationer och prenumerationer.

En exempelrouter visas nedan, spara den i en fil som heter router.ts.

router.ts
router.ts
ts
import { initTRPC } from '@trpc/server';
import { z } from 'zod';
type User = {
id: string;
name: string;
bio?: string;
};
const users: Record<string, User> = {};
export const t = initTRPC.create();
export const appRouter = t.router({
getUserById: t.procedure.input(z.string()).query((opts) => {
return users[opts.input]; // input type is string
}),
createUser: t.procedure
.input(
z.object({
name: z.string().min(3),
bio: z.string().max(142).optional(),
}),
)
.mutation((opts) => {
const id = Date.now().toString();
const user: User = { id, ...opts.input };
users[user.id] = user;
return user;
}),
});
// export type definition of API
export type AppRouter = typeof appRouter;
router.ts
ts
import { initTRPC } from '@trpc/server';
import { z } from 'zod';
type User = {
id: string;
name: string;
bio?: string;
};
const users: Record<string, User> = {};
export const t = initTRPC.create();
export const appRouter = t.router({
getUserById: t.procedure.input(z.string()).query((opts) => {
return users[opts.input]; // input type is string
}),
createUser: t.procedure
.input(
z.object({
name: z.string().min(3),
bio: z.string().max(142).optional(),
}),
)
.mutation((opts) => {
const id = Date.now().toString();
const user: User = { id, ...opts.input };
users[user.id] = user;
return user;
}),
});
// export type definition of API
export type AppRouter = typeof appRouter;

Om din router-fil börjar bli för stor, dela upp den i flera subrouters där varje implementeras i sin egen fil. Slå sedan ihop dem till en enda rot-appRouter.

Skapa contexten

Sedan behöver du en context som skapas för varje förfrågan.

Ett exempel på en context visas nedan, spara den i en fil som heter context.ts:

context.ts
context.ts
ts
import { CreateFastifyContextOptions } from '@trpc/server/adapters/fastify';
export function createContext({ req, res }: CreateFastifyContextOptions) {
const user = { name: req.headers.username ?? 'anonymous' };
return { req, res, user };
}
export type Context = Awaited<ReturnType<typeof createContext>>;
context.ts
ts
import { CreateFastifyContextOptions } from '@trpc/server/adapters/fastify';
export function createContext({ req, res }: CreateFastifyContextOptions) {
const user = { name: req.headers.username ?? 'anonymous' };
return { req, res, user };
}
export type Context = Awaited<ReturnType<typeof createContext>>;

Skapa Fastify-server

tRPC innehåller en adapter för Fastify direkt. Denna adapter låter dig konvertera din tRPC-router till ett Fastify-plugin. För att förhindra fel vid stora batchförfrågningar, se till att ställa in Fastify-alternativet maxParamLength till ett lämpligt värde, som visas.

tips

På grund av begränsningar i Fastifys pluginsystem och typinferens kan det uppstå problem med att få till exempel onError korrekt typad. Du kan lägga till satisfies FastifyTRPCPluginOptions<AppRouter>['trpcOptions'] för att hjälpa TypeScript och få korrekta typer.

server.ts
ts
import {
fastifyTRPCPlugin,
FastifyTRPCPluginOptions,
} from '@trpc/server/adapters/fastify';
import fastify from 'fastify';
import { createContext } from './context';
import { appRouter, type AppRouter } from './router';
const server = fastify({
routerOptions: {
maxParamLength: 5000,
},
});
server.register(fastifyTRPCPlugin, {
prefix: '/trpc',
trpcOptions: {
router: appRouter,
createContext,
onError({ path, error }) {
// report to error monitoring
console.error(`Error in tRPC handler on path '${path}':`, error);
},
} satisfies FastifyTRPCPluginOptions<AppRouter>['trpcOptions'],
});
(async () => {
try {
await server.listen({ port: 3000 });
} catch (err) {
server.log.error(err);
process.exit(1);
}
})();
server.ts
ts
import {
fastifyTRPCPlugin,
FastifyTRPCPluginOptions,
} from '@trpc/server/adapters/fastify';
import fastify from 'fastify';
import { createContext } from './context';
import { appRouter, type AppRouter } from './router';
const server = fastify({
routerOptions: {
maxParamLength: 5000,
},
});
server.register(fastifyTRPCPlugin, {
prefix: '/trpc',
trpcOptions: {
router: appRouter,
createContext,
onError({ path, error }) {
// report to error monitoring
console.error(`Error in tRPC handler on path '${path}':`, error);
},
} satisfies FastifyTRPCPluginOptions<AppRouter>['trpcOptions'],
});
(async () => {
try {
await server.listen({ port: 3000 });
} catch (err) {
server.log.error(err);
process.exit(1);
}
})();

Dina endpoints är nu tillgängliga via HTTP!

EndpointHTTP URI
getUserGET http://localhost:3000/trpc/getUserById?input=INPUT

where INPUT is a URI-encoded JSON string.
createUserPOST http://localhost:3000/trpc/createUser

with req.body of type User

Aktivera WebSockets

Fastify-adaptern stöder WebSockets via plugin:et @fastify/websocket. Allt du behöver göra utöver stegen ovan är att installera beroendet, lägga till prenumerationer i din router och aktivera alternativet useWSS i plugin:et. Den lägsta Fastify-version som krävs för @fastify/websocket är 3.11.0.

Installera beroenden

bash
yarn add @fastify/websocket
bash
yarn add @fastify/websocket

Importera och registrera @fastify/websocket

ts
import ws from '@fastify/websocket';
server.register(ws);
ts
import ws from '@fastify/websocket';
server.register(ws);

Lägg till prenumerationer

Redigera filen router.ts som skapades i de tidigare stegen och lägg till följande kod:

router.ts
ts
import { initTRPC } from '@trpc/server';
import { observable } from '@trpc/server/observable';
const t = initTRPC.create();
export const appRouter = t.router({
randomNumber: t.procedure.subscription(async function* () {
while (true) {
yield { randomNumber: Math.random() };
await new Promise((resolve) => setTimeout(resolve, 1000));
}
}),
});
router.ts
ts
import { initTRPC } from '@trpc/server';
import { observable } from '@trpc/server/observable';
const t = initTRPC.create();
export const appRouter = t.router({
randomNumber: t.procedure.subscription(async function* () {
while (true) {
yield { randomNumber: Math.random() };
await new Promise((resolve) => setTimeout(resolve, 1000));
}
}),
});

Aktivera alternativet useWSS

server.ts
ts
server.register(fastifyTRPCPlugin, {
useWSS: true,
// Enable heartbeat messages to keep connection open (disabled by default)
keepAlive: {
enabled: true,
// server ping message interval in milliseconds
pingMs: 30000,
// connection is terminated if pong message is not received in this many milliseconds
pongWaitMs: 5000,
},
// ...
});
server.ts
ts
server.register(fastifyTRPCPlugin, {
useWSS: true,
// Enable heartbeat messages to keep connection open (disabled by default)
keepAlive: {
enabled: true,
// server ping message interval in milliseconds
pingMs: 30000,
// connection is terminated if pong message is not received in this many milliseconds
pongWaitMs: 5000,
},
// ...
});

Det är helt okej, du kan prenumerera på ämnet randomNumber och du bör få ett slumpmässigt nummer varje sekund 🚀.

Fastify-plugin-alternativ

nametypeoptionaldefaultdescription
prefixstringtrue"/trpc"
useWSSbooleantruefalse
trpcOptionsNodeHTTPHandlerOptionsfalsen/a