メインコンテンツにスキップ

TanStack Start で Prisma ORM を使用する方法

10 分

はじめに

Prisma ORM はデータベースのインタラクションを簡素化し、TanStack Start は最新の React アプリケーションを構築するための堅牢なフレームワークを提供します。Prisma Postgres と組み合わせることで、タイプセーフなクエリと効率的なデータ管理を備えたシームレスなフルスタック開発体験を提供します。

このガイドでは、TanStack Start プロジェクトに Prisma Postgres データベースと Prisma ORM をゼロから統合する手順を説明します。

前提条件

このガイドを開始する前に、以下がインストールされていることを確認してください。

  • Node.js 18 以降がインストールされていること
  • Prisma Postgres データベース (または任意の PostgreSQL データベース)

ステップ 1: TanStack Start プロジェクトの初期化

まず、新しい TanStack Start プロジェクトを作成します。プロジェクトを作成したいディレクトリで、次のコマンドを実行します。

mkdir prisma-tanstack-start-demo
cd prisma-tanstack-start-demo
npm init -y

これにより、prisma-tanstack-start-demo という新しいフォルダが作成され、そのフォルダに移動し、新しい Node.js プロジェクトが初期化されます。

IDE でディレクトリを開き、次の構成で tsconfig.json ファイルを作成します。

tsconfig.json
{
"compilerOptions": {
"jsx": "react-jsx",
"moduleResolution": "Bundler",
"module": "ESNext",
"target": "ES2022",
"skipLibCheck": true,
"strictNullChecks": true
}
}

.gitignore ファイルも必要なので、今すぐセットアップしましょう。

.gitignore
node_modules
.env

次に、TanStack Router と Vinxi をインストールします。TanStack Start は現在これらを必要とするためです。

npm install @tanstack/react-start @tanstack/react-router vinxi

React、Vite React プラグイン、および TypeScript も必要です。

npm install react react-dom
npm install --save-dev @vitejs/plugin-react vite-tsconfig-paths
npm install --save-dev typescript @types/react @types/react-dom

package.json を更新して、Vinxi の CLI を使用するようにします。"type": "module" を追加し、Vinxi の CLI を使用するようにスクリプトを変更します。

package.json
{
"type": "module",
"scripts": {
"dev": "vinxi dev",
"build": "vinxi build",
"start": "vinxi start"
}
}

次に、TanStack Start の app.config.ts ファイルを作成および構成します。

app.config.ts
import { defineConfig } from '@tanstack/react-start/config'
import tsConfigPaths from 'vite-tsconfig-paths'

export default defineConfig({
vite: {
plugins: [
tsConfigPaths({
projects: ['./tsconfig.json'],
}),
],
},
})

TanStack Start が機能するためには、~/app/ に 4 つのファイルが必要です。

  • router.tsx (ルーター構成)
  • ssr.tsx (サーバーエントリーポイント)
  • client.tsx (クライアントエントリーポイント)
  • routes/__root.tsx (アプリのルート)

router.tsx は、ルート定義と設定を使用してアプリケーションのメインルーターを構成します。

app/router.tsx
import { createRouter as createTanStackRouter } from '@tanstack/react-router'
import { routeTree } from './routeTree.gen'

export function createRouter() {
const router = createTanStackRouter({
routeTree,
scrollRestoration: true,
})

return router
}

declare module '@tanstack/react-router' {
interface Register {
router: ReturnType<typeof createRouter>
}
}
注記

routeTree.gen.ts が存在しないというエラーが表示されるはずです。これは想定どおりです。TanStack Start を初めて実行すると生成されます。

ssr.tsx を使用すると、ユーザーが特定のルートにアクセスしたときに実行する必要があるルートとローダーを知ることができます。

app/ssr.tsx
import {
createStartHandler,
defaultStreamHandler,
} from '@tanstack/react-start/server'
import { getRouterManifest } from '@tanstack/react-start/router-manifest'

import { createRouter } from './router'

export default createStartHandler({
createRouter,
getRouterManifest,
})(defaultStreamHandler)

client.tsx は、ブラウザでルートを処理するためのクライアントサイドロジックを初期化します。

app/client.tsx
import { hydrateRoot } from "react-dom/client";
import { StartClient } from "@tanstack/react-start/client";
import { createRouter } from "./router";

const router = createRouter();

hydrateRoot(document, <StartClient router={router} />);

routes/__root.tsx は、アプリケーション全体のルートルートとグローバル HTML レイアウトを定義します。

app/routes/__root.tsx
import type { ReactNode } from "react";
import {
Outlet,
createRootRoute,
HeadContent,
Scripts,
} from "@tanstack/react-router";

export const Route = createRootRoute({
head: () => ({
meta: [
{
charSet: "utf-8",
},
{
name: "viewport",
content: "width=device-width, initial-scale=1",
},
{
title: "Prisma TanStack Start Demo",
},
],
}),
component: RootComponent,
});

function RootComponent() {
return (
<RootDocument>
<Outlet />
</RootDocument>
);
}

function RootDocument({ children }: Readonly<{ children: ReactNode }>) {
return (
<html>
<head>
<HeadContent />
</head>
<body>
{children}
<Scripts />
</body>
</html>
);
}

app/routes/index.tsx という名前のファイルをもう 1 つ作成します。

app/routes/index.tsx
import { createFileRoute } from "@tanstack/react-router";

export const Route = createFileRoute("/")({
component: Home,
});

function Home() {
return (
<div>
<h1>Posts</h1>
</div>
);
}

次に、実行します。

npm run dev

これにより、routeTree.gen.ts ファイルが生成され、ルーティングエラーが解決されます。

ファイルツリーは次のようになります。

.
├── app/
│ ├── routes/
│ │ ├── __root.tsx
│ │ └── index.tsx
│ ├── client.tsx
│ ├── router.tsx
│ ├── routeTree.gen.ts
│ └── ssr.tsx
├── .gitignore
├── app.config.ts
├── package-lock.json
├── package.json
└── tsconfig.json

ステップ 2: Prisma ORM のインストールと構成

次に、Prisma ORM をプロジェクトにインストールしてセットアップする必要があります。まず、Prisma CLI をインストールしましょう。

2.1 Prisma ORM のインストールとモデルの定義

まず、必要な依存関係をインストールします。プロジェクトのルートで、次を実行します。

npm install prisma --save-dev

Prisma CLI がインストールされました。

次に、次のコマンドを実行し、プロンプトに従って Prisma をセットアップします。

npx prisma init --db

このコマンドは次のことを行います。

  • prisma ディレクトリを schema.prisma ファイルとともに作成します。
  • Prisma Postgres データベースを作成します。
  • プロジェクトルートに DATABASE_URL を含む .env ファイルを作成します。
  • 生成された Prisma Client を app/generated/prisma ディレクトリに出力します。

schema.prisma で、Post のモデルを作成し、ジェネレーターを prisma-client プロバイダーを使用するように変更します。

prisma/schema.prisma
generator client {
provider = "prisma-client"
provider = "prisma-client-js"
output = "../app/generated/prisma"
}

datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}

model Post {
id Int @id @default(autoincrement())
title String
content String?
}

データベースを移行するには、次を実行します。

npx prisma migrate dev --name init --output ../app/generated/prisma

これは 3 つのことを行います。

  • prisma/migrations ディレクトリに新しい SQL マイグレーションファイルを作成します。
  • データベースに対して SQL マイグレーションファイルを実行します。
  • prisma generate を内部で実行します。これにより、@prisma/client パッケージがインストールされ、モデルに基づいてカスタマイズされた Prisma Client API が生成されます。

データベースを表示するには、次を実行します。

npx prisma studio

Post テーブルを選択し、レコードを追加します。

情報

Prisma Studio を使用する代わりに、次のコマンドを使用してデータベースにデータをシードできます。詳細については、Prisma Seed を参照してください。

まだアプリで投稿を確認できないので、修正しましょう。

2.2 index.tsx でのデータのフェッチと表示

データベースに追加した投稿をフェッチするように index.tsx をセットアップしましょう。まず、必要なモジュールをインポートします。

app/routes/index.tsx
import { PrismaClient } from "../generated/prisma";
import { createServerFn } from "@tanstack/react-start";

Prisma Client のインスタンスを作成します。

app/routes/index.tsx
const prisma = new PrismaClient();

TanStack Start の createServerFn を使用してサーバー関数を作成し、.findMany() を使用してデータベースから投稿をフェッチします。

app/routes/index.tsx
const getPosts = createServerFn({ method: "GET" }).handler(async () => {
return prisma.post.findMany();
});

TanStack Start では、createFileRoute 関数のローダー関数を使用して、ロード時に関数を実行できます。次のコードを使用して、ロード時に投稿をフェッチします。

app/routes/index.tsx
export const Route = createFileRoute("/")({
component: Home,
loader: () => {
return getPosts();
},
});

Route.useLoaderData() を使用して、ローダーからのレスポンスをメインコンポーネントに保存します。

app/routes/index.tsx
function Home() {
const posts = Route.useLoaderData();

return (
<div>
<h1>Posts</h1>
</div>
);
}

投稿をマップしてリストに表示します。

app/routes/index.tsx
function Home() {
const posts = Route.useLoaderData();

return (
<div>
<h1>Posts</h1>
<ul>
{posts.map((post) => (
<li key={post.id}>
<h3>{post.title}</h3>
<p>{post.content}</p>
</li>
))}
</ul>
</div>
);
}

この設定により、データベースから直接フェッチされた投稿がページに表示されます。

次のステップ

Prisma ORM と TanStack Start を正常に統合し、シームレスなフルスタックアプリケーションを作成しました。次にできることの提案をいくつか示します。

  • より複雑なデータ関係を処理するために Prisma モデルを拡張します。
  • アプリケーションの機能を強化するために、追加の CRUD 操作を実装します。
  • Prisma と TanStack Start のより多くの機能を調べて、理解を深めます。
  • アプリケーションをスケールする方法については、Prisma Postgres を確認してください。

詳細情報


Prisma とのつながりを保つ

以下とつながることで、Prisma の旅を続けましょう。 アクティブなコミュニティ。常に情報を入手し、参加し、他の開発者と協力しましょう。

私たちは皆様のご参加を心から歓迎し、コミュニティの一員として皆様をお迎えできることを楽しみにしています!