Fastify 어댑터
이 페이지는 PageTurner AI로 번역되었습니다(베타). 프로젝트 공식 승인을 받지 않았습니다. 오류를 발견하셨나요? 문제 신고 →
예시 애플리케이션
Fastify 어댑터를 시작하는 가장 좋은 방법은 예시 애플리케이션을 살펴보는 것입니다.
| Description | Links |
|---|---|
|
Fastify에서 tRPC 사용하기
의존성 설치
bashyarn add @trpc/server fastify zod
bashyarn add @trpc/server fastify zod
⚠️ Fastify 버전 요구사항
tRPC v11 Fastify 어댑터는 Fastify v5 이상이 필요합니다. Fastify v4를 사용하면 오류 없이 빈 응답이 반환될 수 있습니다.
Zod는 필수 의존성이 아니지만, 아래 샘플 라우터에서 사용됩니다.
라우터 생성
먼저 쿼리, 뮤테이션, 서브스크립션을 처리할 라우터가 필요합니다.
아래에 샘플 라우터가 있습니다. router.ts 파일로 저장하세요.
router.ts
router.tstsimport { 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 APIexport type AppRouter = typeof appRouter;
router.tstsimport { 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 APIexport type AppRouter = typeof appRouter;
라우터 파일이 너무 커지기 시작하면, 라우터를 여러 서브 라우터로 분할하고 각각을 별도의 파일로 구현하세요. 그런 다음 이들을 병합하여 단일 루트 appRouter로 만드세요.
컨텍스트 생성
그런 다음 각 요청마다 생성될 컨텍스트가 필요합니다.
아래에 샘플 컨텍스트가 있습니다. context.ts 파일로 저장하세요:
context.ts
context.tstsimport { 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.tstsimport { 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>>;
Fastify 서버 생성
tRPC는 Fastify 어댑터를 기본 제공합니다. 이 어댑터는 tRPC 라우터를 Fastify 플러그인으로 변환합니다. 대규모 배치 요청 시 오류를 방지하려면 표시된 대로 maxParamLength Fastify 옵션을 적절한 값으로 설정하세요.
Fastify의 플러그인 시스템과 타입 추론의 한계로 인해 onError 같은 요소의 타입 지정에 문제가 발생할 수 있습니다. satisfies FastifyTRPCPluginOptions<AppRouter>['trpcOptions']를 추가하여 TypeScript가 올바른 타입을 추론하도록 도울 수 있습니다.
server.tstsimport {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 monitoringconsole.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.tstsimport {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 monitoringconsole.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);}})();
이제 엔드포인트를 HTTP를 통해 사용할 수 있습니다!
| Endpoint | HTTP URI |
|---|---|
getUser | GET http://localhost:3000/trpc/getUserById?input=INPUT where INPUT is a URI-encoded JSON string. |
createUser | POST http://localhost:3000/trpc/createUser with req.body of type User |
WebSockets 활성화
Fastify 어댑터는 @fastify/websocket 플러그인을 통해 WebSockets을 지원합니다. 위 단계 외에 의존성 설치, 라우터에 서브스크립션 추가, 플러그인에서 useWSS 옵션 활성화만 하면 됩니다. @fastify/websocket에 필요한 최소 Fastify 버전은 3.11.0입니다.
의존성 설치
bashyarn add @fastify/websocket
bashyarn add @fastify/websocket
@fastify/websocket 가져오기 및 등록
tsimport ws from '@fastify/websocket';server.register(ws);
tsimport ws from '@fastify/websocket';server.register(ws);
서브스크립션 추가
이전 단계에서 생성한 router.ts 파일을 편집하고 다음 코드를 추가하세요:
router.tstsimport { 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.tstsimport { 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));}}),});
useWSS 옵션 활성화
server.tstsserver.register(fastifyTRPCPlugin, {useWSS: true,// Enable heartbeat messages to keep connection open (disabled by default)keepAlive: {enabled: true,// server ping message interval in millisecondspingMs: 30000,// connection is terminated if pong message is not received in this many millisecondspongWaitMs: 5000,},// ...});
server.tstsserver.register(fastifyTRPCPlugin, {useWSS: true,// Enable heartbeat messages to keep connection open (disabled by default)keepAlive: {enabled: true,// server ping message interval in millisecondspingMs: 30000,// connection is terminated if pong message is not received in this many millisecondspongWaitMs: 5000,},// ...});
이제 randomNumber 토픽을 구독할 수 있으며 매초 임의의 숫자를 받을 수 있습니다 🚀.
Fastify 플러그인 옵션
| name | type | optional | default | description |
|---|---|---|---|---|
| prefix | string | true | "/trpc" | |
| useWSS | boolean | true | false | |
| trpcOptions | NodeHTTPHandlerOptions | false | n/a |