1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

tRPCとは?

TypeScript Remote Procedure Callの略
tRPCを利用することで、TypeScriptで定義した型をフロントエンドとバックエンドの双方で共有し、API通信を一貫した型安全性のもとに行える。結果として、IDEの自動補完や型推論のサポートをフルに活用しつつ、クライアントとサーバー間のデータ構造の不一致やバグを未然に防ぎ、効率的な開発を実現できる。

実際に使ってみる

今回はNext.js, trpc, zodを利用してモノレポ構成で利用する。

必要なライブラリのインストール

npm install @trpc/server@next @trpc/client@next @trpc/react-query@next zod

サーバーサイドの実装

trpcのルーターを定義する

trpc/router.ts
import { initTRPC } from '@trpc/server';
import { z } from 'zod';

const t = initTRPC.create();

export const appRouter = t.router({
  greeting: t.procedure
    .input(z.object({ name: z.string() }))
    .query(({ input }) => {
      return { message: `Hello, ${input.name}!` };
    }),
});

// クライアント用の型
export type AppRouter = typeof appRouter;

trpcエンドポイントの定義

app/api/trpc/[trpc]/route.ts
import { NextRequest } from 'next/server';
import { fetchRequestHandler } from '@trpc/server/adapters/fetch';
import { appRouter } from '@/trpc/router';

export const runtime = 'edge'; // Edge Runtime で動かす場合 (任意)

const handler = (req: NextRequest) => {
  return fetchRequestHandler({
    router: appRouter,
    req,
    endpoint: '/api/trpc',
    createContext: () => ({}),
  });
};

export { handler as GET, handler as POST };

クライアントサイドの実装

trpcクライアントの作成

utils/trpcClient.ts
import { createTRPCProxyClient, httpBatchLink } from '@trpc/client';
import type { AppRouter } from '@/trpc/router';

export const trpcClient = createTRPCProxyClient<AppRouter>({
  links: [
    httpBatchLink({
      url: '/api/trpc', // tRPC のエンドポイント
    }),
  ],
});

画面の作成

app/page.tsx
'use client';

import React, { useState } from 'react';
import { trpcClient } from '@/utils/trpcClient';

export default function Home() {
  const [name, setName] = useState('Alice');
  const [result, setResult] = useState<string | null>(null);
  const [loading, setLoading] = useState(false);

  const handleClick = async () => {
    setLoading(true);
    try {
      // tRPC の greeting メソッドを呼び出し
      const response = await trpcClient.greeting.query({ name });
      setResult(response.message);
    } catch (error) {
      console.error(error);
      setResult('エラーが発生しました');
    } finally {
      setLoading(false);
    }
  };

  return (
    <main style={{ padding: '1rem' }}>
      <h1>tRPC + Next.js + Zod Example</h1>
      <div style={{ marginBottom: '0.5rem' }}>
        <input
          type="text"
          value={name}
          placeholder="Enter your name"
          onChange={(e) => setName(e.target.value)}
        />
      </div>
      <button onClick={handleClick} disabled={loading}>
        {loading ? 'Loading...' : 'Get Greeting'}
      </button>
      <div style={{ marginTop: '1rem' }}>
        {result && <p>{result}</p>}
      </div>
    </main>
  );
}

ブラウザからページを開き適当な文字を入力してGet Greetingを押すとapiが呼び出され入力した文字列が表示される。
これでフロントエンドとバックエンドの双方で型を共有しIDEの自動補完やAPI通信を型安全に行える。

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?