tRPCは、TypeScript同士のフロントエンドとバックエンドをスキーマ定義なしで型安全に繋ぐライブラリです。OpenAPIやGraphQL Code Generatorのような中間生成工程が不要で、関数呼び出しのような自然な書き心地でAPIを利用できます。本記事では、tRPCの基本構成と導入手順を解説します。
tRPCとは
tRPCは「Type-safe Remote Procedure Call」の略で、サーバー側で定義したProcedureの型情報をクライアントが直接インポートして使う仕組みです。サーバーの変更がコンパイル時にクライアントで検知できるため、APIの破壊的変更による事故を未然に防げます。
tRPCの構成要素
- Router:Procedureの集まり(REST APIで言うコントローラ相当)
- Procedure:query(取得)またはmutation(更新)の単位
- Context:認証情報・DBクライアントなどリクエスト共通の情報
- Input検証:Zodなどでバリデーション
サーバー側の実装例
// server/router.ts
import { initTRPC } from '@trpc/server';
import { z } from 'zod';
const t = initTRPC.create();
export const appRouter = t.router({
hello: t.procedure
.input(z.object({ name: z.string() }))
.query(({ input }) => `Hello, ${input.name}!`),
createUser: t.procedure
.input(z.object({ name: z.string(), email: z.string().email() }))
.mutation(async ({ input }) => {
const user = await db.user.create({ data: input });
return user;
}),
});
export type AppRouter = typeof appRouter;
クライアント側の実装例
// client/trpc.ts
import { createTRPCProxyClient, httpBatchLink } from '@trpc/client';
import type { AppRouter } from '../server/router';
export const trpc = createTRPCProxyClient<AppRouter>({
links: [httpBatchLink({ url: 'http://localhost:3000/api/trpc' })],
});
// component.tsx
const greeting = await trpc.hello.query({ name: 'Alice' });
const user = await trpc.createUser.mutate({ name: 'Bob', email: 'b@x.com' });
引数・戻り値の型がそのままIDEに補完され、型ミスは即エラーになります。
React Queryとの統合
@trpc/react-query を導入すると、useQuery/useMutationのような書き方でtRPCのProcedureを呼べます。キャッシュ・リトライ・楽観更新といったReact Queryの恩恵をそのまま受けられます。
const { data, isLoading } = trpc.hello.useQuery({ name: 'Alice' });
tRPCが向いているケース
- フロントとバックが両方TypeScript(モノレポ含む)
- 少人数チームで素早く型安全なAPIを作りたい
- 外部公開しない社内向け・アプリ向けAPI
- Next.jsのApp RouterやServer Componentsと組み合わせて使いたい
向かないケース
- 外部公開API(言語非依存のスキーマが必要)
- TypeScript以外のクライアントが多数あるケース
- 厳密なREST設計を求められる社内ポリシー
まとめ
tRPCは、TypeScriptモノレポにおける「最短・最強の型安全API」です。スキーマファイル管理や型生成の手間が消え、サーバーの変更が即クライアントの型エラーとなるため、開発速度と安全性が同時に向上します。Next.js + Prisma + tRPCはモダンスタックの定番です。