tRPC 퀵스타트
tRPC 퀵스타트 (Quickstart)
TypeScript 풀스택에서 "서버의 함수를 그대로 클라이언트에서 타입 안전하게 부르고 싶다"는 요구가 많아요. tRPC는 스키마 정의나 코드 생산 없이, 그냥 함수를 정의하고 타입을 공유하는 것만으로 그걸 이루는 프레임워크예요.
tRPC는 여러 패키지로 나뉘어 있어서 필요한 것만 설치해요. 시작은 @trpc/server와 @trpc/client 두 개예요. 요구 사항은 TypeScript >=5.7.2이며, 비공식 지원이라 tsconfig.json에 "strict": true를 쓰는 걸 강력히 권장해요.
npm install @trpc/server @trpc/client
구성은 보통 세 파일로 나눠요 — tRPC를 초기화하는 server/trpc.ts, API 로직과 타입 export를 담는 server/appRouter.ts, HTTP 서버를 띄우는 server/index.ts예요. 이렇게 분리하면 순환 의존성을 피할 수 있어요.
먼저 tRPC 백엔드를 초기화하고, router와 publicProcedure 헬퍼를 export해요.
// server/trpc.ts
import { initTRPC } from '@trpc/server';
const t = initTRPC.create();
export const router = t.router;
export const publicProcedure = t.procedure;
그다음 메인 라우터를 만들고 타입을 export해요. 이 타입이 클라이언트의 타입 안전성의 원천이 돼요.
// server/appRouter.ts
import { publicProcedure, router } from './trpc';
import { z } from 'zod';
export const appRouter = router({
userList: publicProcedure.query(async () => {
return [{ id: '1', name: 'Katt' }];
}),
userById: publicProcedure.input(z.string()).query(async (opts) => {
const { input } = opts;
return { id: input, name: 'Katt' };
}),
userCreate: publicProcedure
.input(z.object({ name: z.string() }))
.mutation(async (opts) => {
const { input } = opts;
return { id: '1', ...input };
}),
});
export type AppRouter = typeof appRouter;
입력 검증은 publicProcedure.input()에 검증기(validator)를 두는 방식이에요. zod·yup·superstruct 같은 검증 라이브러리를 쓸 수 있고, 위 예시는 zod예요. GraphQL처럼 Query와 Mutation을 구분해요 — Query는 읽기 전용이라 HTTP GET, Mutation은 부작용을 일으키는 쓰기라 HTTP POST를 써요. 라우터를 만들었으면 어댑터(여기선 standalone)로 HTTP 서버를 띄워요.
클라이언트에서는 createTRPCClient에 AppRouter 타입을 전달하면, httpBatchLink가 여러 호출을 하나의 HTTP 요청으로 묶어 보내는 것도 자동으로 이뤄져요. 이제 trpc.userById.query('1')처럼 서버 메서드를 타입 안전하게 호출할 수 있어요.
더 알아보기
- 프레임워크별 사용: usage with React, usage with Next.js
- 다양한 서버 어댑터: Server Adapters
Date같은 복합 타입을 유지하려면 superjson: Data Transformers