メインコンテンツへスキップ
バージョン: 11.x

クイックスタート

非公式ベータ版翻訳

このページは PageTurner AI で翻訳されました(ベータ版)。プロジェクト公式の承認はありません。 エラーを見つけましたか? 問題を報告 →

インストール

tRPCは複数のパッケージに分割されているため、必要なものだけをインストールできます。適切なコードベースのセクションにパッケージをインストールしてください。このクイックスタートガイドではシンプルに保つため、バニラクライアントのみを使用します。フレームワーク別ガイドについては、Reactでの使用方法Next.jsでの使用方法をご覧ください。

要件
  • tRPCにはTypeScript >=5.7.2が必要です
  • tsconfig.json"strict": trueを使用することを強く推奨します。非strictモードは公式にサポートしていません

まず、@trpc/server@trpc/clientパッケージをインストールします:

npm install @trpc/server @trpc/client
AIエージェント

AIコーディングエージェントをご利用の場合、より良いコード生成のためにtRPCスキルをインストールしてください:

bash
npx @tanstack/intent@latest install
bash
npx @tanstack/intent@latest install

初めてのtRPC API

tRPCで型安全なAPIを構築する手順を見ていきましょう。最初に、このAPIには以下のTypeScriptシグネチャを持つ3つのエンドポイントが含まれます:

ts
type User = { id: string; name: string; };
userList: () => User[];
userById: (id: string) => User;
userCreate: (data: { name: string }) => User;
ts
type User = { id: string; name: string; };
userList: () => User[];
userById: (id: string) => User;
userCreate: (data: { name: string }) => User;

以下が構築するファイル構造です。循環依存を防ぐため、tRPCの初期化、ルーター定義、サーバー設定は別々のファイルに分離することを推奨します:

.
├── server/
│ ├── trpc.ts # tRPC instantiation & setup
│ ├── appRouter.ts # Your API logic and type export
│ └── index.ts # HTTP server
└── client/
└── index.ts # tRPC client
.
├── server/
│ ├── trpc.ts # tRPC instantiation & setup
│ ├── appRouter.ts # Your API logic and type export
│ └── index.ts # HTTP server
└── client/
└── index.ts # tRPC client

1. ルーターインスタンスの作成

まずtRPCバックエンドを初期化します。tRPCオブジェクト全体ではなく、再利用可能なヘルパー関数をエクスポートするために、別ファイルで行うのが良い慣習です。

server/trpc.ts
ts
import { initTRPC } from '@trpc/server';
 
/**
* Initialization of tRPC backend
* Should be done only once per backend!
*/
const t = initTRPC.create();
 
/**
* Export reusable router and procedure helpers
* that can be used throughout the router
*/
export const router = t.router;
export const publicProcedure = t.procedure;
server/trpc.ts
ts
import { initTRPC } from '@trpc/server';
 
/**
* Initialization of tRPC backend
* Should be done only once per backend!
*/
const t = initTRPC.create();
 
/**
* Export reusable router and procedure helpers
* that can be used throughout the router
*/
export const router = t.router;
export const publicProcedure = t.procedure;

次に、メインのルーターインスタンス(通常appRouterと呼ばれます)を初期化し、後でプロシージャを追加します。最後に、クライアント側で後ほど使用するルーターの型をエクスポートする必要があります。

server/appRouter.ts
ts
import { router } from './trpc';
 
export const appRouter = router({
// ...
});
 
export type AppRouter = typeof appRouter;
server/appRouter.ts
ts
import { router } from './trpc';
 
export const appRouter = router({
// ...
});
 
export type AppRouter = typeof appRouter;

2. クエリプロシージャの追加

ルーターにクエリプロシージャを追加するにはpublicProcedure.query()を使用します。

以下はuserListというクエリプロシージャを作成し、ユーザーリストを返す例です:

server/appRouter.ts
ts
import { publicProcedure, router } from './trpc';
 
export const appRouter = router({
userList: publicProcedure
.query(async () => {
const users: User[] = [{ id: '1', name: 'Katt' }];
 
return users;
}),
});
 
export type AppRouter = typeof appRouter;
server/appRouter.ts
ts
import { publicProcedure, router } from './trpc';
 
export const appRouter = router({
userList: publicProcedure
.query(async () => {
const users: User[] = [{ id: '1', name: 'Katt' }];
 
return users;
}),
});
 
export type AppRouter = typeof appRouter;

3. 入力パーサーを使用したプロシージャ入力の検証

userByIdプロシージャを実装するには、クライアントからの入力を受け入れる必要があります。tRPCでは入力パーサーを定義して入力を検証・解析できます。独自の入力パーサーを定義するか、zodyupsuperstructなどの検証ライブラリを使用できます。

入力パーサーはpublicProcedure.input()で定義し、下記のようにリゾルバー関数からアクセスできます:

The input parser can be any ZodType, e.g. z.string() or z.object().


server/appRouter.ts
ts
import { publicProcedure, router } from './trpc';
import { z } from 'zod';
 
export const appRouter = router({
// ...
userById: publicProcedure
.input(z.string())
.query(async (opts) => {
const { input } = opts;
const input: string
const user: User = { id: input, name: 'Katt' };
 
return user;
}),
});
 
export type AppRouter = typeof appRouter;
server/appRouter.ts
ts
import { publicProcedure, router } from './trpc';
import { z } from 'zod';
 
export const appRouter = router({
// ...
userById: publicProcedure
.input(z.string())
.query(async (opts) => {
const { input } = opts;
const input: string
const user: User = { id: input, name: 'Katt' };
 
return user;
}),
});
 
export type AppRouter = typeof appRouter;

4. ミューテーションプロシージャの追加

GraphQLと同様に、tRPCはQueryプロシージャとMutationプロシージャを区別します。

QueryとMutationの違いは主に意味論的なものです。QueryはHTTP GETを使用し読み取り操作を意図し、MutationはHTTP POSTを使用し副作用を伴う操作を意図します。

ルーターオブジェクトに新しいプロパティとしてuserCreateミューテーションを追加しましょう:

server/appRouter.ts
ts
import { publicProcedure, router } from './trpc';
 
export const appRouter = router({
// ...
userCreate: publicProcedure
.input(z.object({ name: z.string() }))
.mutation(async (opts) => {
const { input } = opts;
const input: { name: string; }
// Create the user in your DB
const user: User = { id: '1', ...input };
 
return user;
}),
});
 
export type AppRouter = typeof appRouter;
server/appRouter.ts
ts
import { publicProcedure, router } from './trpc';
 
export const appRouter = router({
// ...
userCreate: publicProcedure
.input(z.object({ name: z.string() }))
.mutation(async (opts) => {
const { input } = opts;
const input: { name: string; }
// Create the user in your DB
const user: User = { id: '1', ...input };
 
return user;
}),
});
 
export type AppRouter = typeof appRouter;

APIの提供

ルーターを定義したので、提供できます。tRPCには主要なWebサーバー向けのファーストクラスアダプターがあります。シンプルにするため、ここではNode.js向けstandaloneアダプターを使用します。

server/index.ts
ts
import { createHTTPServer } from '@trpc/server/adapters/standalone';
import { appRouter } from './appRouter';
 
const server = createHTTPServer({
router: appRouter,
});
 
server.listen(3000);
server/index.ts
ts
import { createHTTPServer } from '@trpc/server/adapters/standalone';
import { appRouter } from './appRouter';
 
const server = createHTTPServer({
router: appRouter,
});
 
server.listen(3000);
See the full backend code
server/trpc.ts
ts
import { initTRPC } from '@trpc/server';
 
const t = initTRPC.create();
 
export const router = t.router;
export const publicProcedure = t.procedure;
server/trpc.ts
ts
import { initTRPC } from '@trpc/server';
 
const t = initTRPC.create();
 
export const router = t.router;
export const publicProcedure = t.procedure;

server/appRouter.ts
ts
import { z } from "zod";
import { publicProcedure, router } from "./trpc";
 
type User = { id: string; name: string };
 
export const appRouter = router({
userList: publicProcedure
.query(async () => {
const users: User[] = [{ id: '1', name: 'Katt' }];
return users;
}),
userById: publicProcedure
.input(z.string())
.query(async (opts) => {
const { input } = opts;
const user: User = { id: input, name: 'Katt' };
return user;
}),
userCreate: publicProcedure
.input(z.object({ name: z.string() }))
.mutation(async (opts) => {
const { input } = opts;
const user: User = { id: '1', ...input };
return user;
}),
});
 
export type AppRouter = typeof appRouter;
server/appRouter.ts
ts
import { z } from "zod";
import { publicProcedure, router } from "./trpc";
 
type User = { id: string; name: string };
 
export const appRouter = router({
userList: publicProcedure
.query(async () => {
const users: User[] = [{ id: '1', name: 'Katt' }];
return users;
}),
userById: publicProcedure
.input(z.string())
.query(async (opts) => {
const { input } = opts;
const user: User = { id: input, name: 'Katt' };
return user;
}),
userCreate: publicProcedure
.input(z.object({ name: z.string() }))
.mutation(async (opts) => {
const { input } = opts;
const user: User = { id: '1', ...input };
return user;
}),
});
 
export type AppRouter = typeof appRouter;

server/index.ts
ts
import { createHTTPServer } from "@trpc/server/adapters/standalone";
import { appRouter } from "./appRouter";
 
const server = createHTTPServer({
router: appRouter,
});
 
server.listen(3000);
server/index.ts
ts
import { createHTTPServer } from "@trpc/server/adapters/standalone";
import { appRouter } from "./appRouter";
 
const server = createHTTPServer({
router: appRouter,
});
 
server.listen(3000);

クライアント側での新しいバックエンドの使用

クライアントサイドのコードに移り、エンドツーエンドのタイプセーフティの力を実感しましょう。クライアントで使用するためにAppRouter型をインポートするだけで、実装の詳細をクライアントに漏らすことなくシステム全体の完全なタイプセーフティを実現できます。

1. tRPCクライアントのセットアップ

client/index.ts
ts
import { createTRPCClient, httpBatchLink } from '@trpc/client';
import type { AppRouter } from './appRouter';
// 👆 **type-only** imports are stripped at build time
 
// Pass AppRouter as a type parameter. 👇 This lets `trpc` know
// what procedures are available on the server and their input/output types.
const trpc = createTRPCClient<AppRouter>({
links: [
httpBatchLink({
url: 'http://localhost:3000',
}),
],
});
client/index.ts
ts
import { createTRPCClient, httpBatchLink } from '@trpc/client';
import type { AppRouter } from './appRouter';
// 👆 **type-only** imports are stripped at build time
 
// Pass AppRouter as a type parameter. 👇 This lets `trpc` know
// what procedures are available on the server and their input/output types.
const trpc = createTRPCClient<AppRouter>({
links: [
httpBatchLink({
url: 'http://localhost:3000',
}),
],
});

tRPCのリンクはGraphQLのリンクと似ており、サーバーへのデータフローを制御できます。上記の例ではhttpBatchLinkを使用しており、複数の呼び出しを自動的に単一のHTTPリクエストにバッチ処理します。リンクの詳細な使用法については、リンクドキュメントを参照してください。

2. 型推論とオートコンプリート

これでtrpcオブジェクトを通じてAPIプロシージャにアクセスできます。実際に試してみましょう!

client/index.ts
ts
// Inferred types
const user = await trpc.userById.query('1');
const user: User
 
const createdUser = await trpc.userCreate.mutate({ name: 'Katt' });
const createdUser: User
client/index.ts
ts
// Inferred types
const user = await trpc.userById.query('1');
const user: User
 
const createdUser = await trpc.userCreate.mutate({ name: 'Katt' });
const createdUser: User

クライアント側でオートコンプリートを使用してAPIを探索することもできます

client/index.ts
ts
trpc.u;
      
 
 
client/index.ts
ts
trpc.u;
      
 
 

次のステップ

What's next?Description
Example AppsExplore tRPC in your chosen framework
TanStack React QueryRecommended React integration via @trpc/tanstack-react-query
Next.jsUsage with Next.js
Server AdaptersExpress, Fastify, and more
TransformersUse superjson to retain complex types like Date