본문 바로가기
버전: 9.x

빠른 시작

비공식 베타 번역

이 페이지는 PageTurner AI로 번역되었습니다(베타). 프로젝트 공식 승인을 받지 않았습니다. 오류를 발견하셨나요? 문제 신고 →

tRPC를 최대한 원활하게 체험하고 시작하려면 예제 앱들을 꼭 확인해보시기 바랍니다.

설치

⚠️ 필수 조건: tRPC는 템플릿 리터럴 타입에 의존하므로 TypeScript > 4.1 버전이 필요합니다.

npm install @trpc/server

tRPC 엔드포인트와 라우터 구현용. 서버 코드베이스에 설치하세요.

npm install @trpc/client @trpc/server

클라이언트에서 타입 안전한 API 호출을 위한 패키지. 클라이언트 코드베이스에 설치하세요 (@trpc/server@trpc/client의 피어 종속성입니다).

npm install @trpc/react react-query@3

tRPC API를 쿼리하기 위한 강력한 React 훅 세트 생성용. react-query 기반.

npm install @trpc/next

Next.js와 tRPC 통합을 위한 유틸리티 세트.

설치 스니펫

npm:

bash
npm install @trpc/server @trpc/client @trpc/react react-query@3 @trpc/next
bash
npm install @trpc/server @trpc/client @trpc/react react-query@3 @trpc/next

yarn:

bash
yarn add @trpc/server @trpc/client @trpc/react react-query@3 @trpc/next
bash
yarn add @trpc/server @trpc/client @trpc/react react-query@3 @trpc/next

라우터 정의하기

tRPC로 타입 안전한 API를 구축하는 단계를 살펴보겠습니다. 시작 단계에서 이 API는 두 개의 엔드포인트만 포함할 것입니다:

ts
getUser(id: string) => { id: string; name: string; }
createUser(data: {name:string}) => { id: string; name: string; }
ts
getUser(id: string) => { id: string; name: string; }
createUser(data: {name:string}) => { id: string; name: string; }

라우터 인스턴스 생성하기

먼저 서버 코드베이스 어딘가에 라우터를 정의합니다:

server.ts
ts
import * as trpc from '@trpc/server';
const appRouter = trpc.router();
// only export *type signature* of router!
// to avoid accidentally importing your API
// into client-side code
export type AppRouter = typeof appRouter;
server.ts
ts
import * as trpc from '@trpc/server';
const appRouter = trpc.router();
// only export *type signature* of router!
// to avoid accidentally importing your API
// into client-side code
export type AppRouter = typeof appRouter;

쿼리 엔드포인트 추가하기

라우터에 쿼리 엔드포인트를 추가하려면 .query() 메서드를 사용하세요. 인수:

.query(name: string, params: QueryParams)

  • name: string: 이 엔드포인트의 이름

  • params.input: 선택 사항. 이 엔드포인트의 입력을 검증/캐스팅하는 함수로, 유효한 경우 강력한 타입의 값을 반환하거나 유효하지 않은 경우 오류를 발생시켜야 합니다. 또는 Zod, Superstruct, Yup 스키마를 전달할 수 있습니다.

  • params.resolve: 엔드포인트의 실제 구현체. 단일 req 인수를 가진 함수입니다. 검증된 입력은 req.input으로 전달되고 컨텍스트는 req.ctx에 위치합니다(컨텍스트에 대해서는 나중에 자세히 설명).

server.ts
ts
import * as trpc from '@trpc/server';
const appRouter = trpc.router().query('getUser', {
input: (val: unknown) => {
if (typeof val === 'string') return val;
throw new Error(`Invalid input: ${typeof val}`);
},
async resolve(req) {
req.input; // string
return { id: req.input, name: 'Bilbo' };
},
});
export type AppRouter = typeof appRouter;
server.ts
ts
import * as trpc from '@trpc/server';
const appRouter = trpc.router().query('getUser', {
input: (val: unknown) => {
if (typeof val === 'string') return val;
throw new Error(`Invalid input: ${typeof val}`);
},
async resolve(req) {
req.input; // string
return { id: req.input, name: 'Bilbo' };
},
});
export type AppRouter = typeof appRouter;

변경(mutation) 엔드포인트 추가하기

GraphQL과 유사하게 tRPC는 쿼리와 변경(mutation) 엔드포인트를 구분합니다. createUser 변경을 추가해 보겠습니다:

ts
createUser(payload: {name: string}) => {id: string; name: string};
ts
createUser(payload: {name: string}) => {id: string; name: string};
server.ts
ts
import * as trpc from '@trpc/server';
import { z } from 'zod';
const appRouter = trpc
.router()
.query('getUser', {
input: (val: unknown) => {
if (typeof val === 'string') return val;
throw new Error(`Invalid input: ${typeof val}`);
},
async resolve(req) {
req.input; // string
return { id: req.input, name: 'Bilbo' };
},
})
.mutation('createUser', {
// validate input with Zod
input: z.object({ name: z.string().min(5) }),
async resolve(req) {
// use your ORM of choice
return await UserModel.create({
data: req.input,
});
},
});
export type AppRouter = typeof appRouter;
server.ts
ts
import * as trpc from '@trpc/server';
import { z } from 'zod';
const appRouter = trpc
.router()
.query('getUser', {
input: (val: unknown) => {
if (typeof val === 'string') return val;
throw new Error(`Invalid input: ${typeof val}`);
},
async resolve(req) {
req.input; // string
return { id: req.input, name: 'Bilbo' };
},
})
.mutation('createUser', {
// validate input with Zod
input: z.object({ name: z.string().min(5) }),
async resolve(req) {
// use your ORM of choice
return await UserModel.create({
data: req.input,
});
},
});
export type AppRouter = typeof appRouter;

다음 단계

tRPC에는 일반적으로 React 프로젝트와 특히 Next.js를 위해 설계된 더 정교한 클라이언트 측 도구가 포함되어 있습니다. 다음 적절한 가이드를 읽어보세요: