Prisma ORMをSolidStartで使用する方法
はじめに
Prisma ORMは、型安全なクエリとスムーズな開発者エクスペリエンスにより、データベースアクセスを効率化します。SolidJSでリアクティブなWebアプリを構築するためのモダンなフレームワークであるSolidStartは、PrismaおよびPostgresと相性が良く、クリーンでスケーラブルなフルスタックアーキテクチャを構築できます。
このガイドでは、Prisma ORMをPrisma PostgresデータベースとゼロからSolidStartプロジェクトに統合する方法を学びます。このガイドの完全な例は、GitHubで確認できます。
前提条件
1. プロジェクトのセットアップ
まず、新しいSolidStartアプリを作成します。ターミナルで以下を実行します。
npm init solid@latest
プロンプトが表示されたら、以下のオプションを使用します。
- プロジェクト名:
my-solid-prisma-app
- SolidStartプロジェクトですか:
はい
- テンプレート:
bare
- TypeScriptを使用しますか:
はい
次に、新しいプロジェクトに移動し、依存関係をインストールして開発サーバーを起動します。
cd my-solid-prisma-app
npm install
npm run dev
開発サーバーが起動したら、ブラウザでhttps://:3000
を開きます。SolidStartのウェルカム画面が表示されるはずです。
app.tsx
ファイルを編集し、その内容を以下のコードに置き換えることで、デフォルトのUIをクリーンアップします。
import "./app.css";
export default function App() {
return (
<main>
<h1>SolidStart + Prisma</h1>
</main>
);
}
2. Prismaのインストールと設定
2.1. 依存関係のインストール
Prismaの使用を開始するには、いくつかの依存関係をインストールする必要があります。
- Prisma Postgres (推奨)
- その他のデータベース
npm install prisma tsx --save-dev
npm install @prisma/extension-accelerate @prisma/client
npm install prisma tsx --save-dev
npm install @prisma/client
インストール後、プロジェクトでPrismaを初期化します。
npx prisma init --db --output ../src/generated/prisma
Prisma Postgresデータベースのセットアップ中にいくつかの質問に答える必要があります。お住まいの地域に最も近いリージョンと、「My SolidStart Project」のような覚えやすいデータベース名を選択してください。
これにより以下が作成されます。
prisma
ディレクトリと、その中にschema.prisma
ファイル。- Prisma Postgresデータベース。
- プロジェクトルートに
DATABASE_URL
を含む.env
ファイル。 - 生成されたPrisma Client用の
src/generated/prisma
というoutput
ディレクトリ。
2.2. Prismaスキーマの定義
prisma/schema.prisma
ファイルに、以下のモデルを追加し、ジェネレーターがprisma-client
プロバイダーを使用するように変更します。
generator client {
provider = "prisma-client"
output = "../src/generated/prisma"
}
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
model User {
id Int @id @default(autoincrement())
email String @unique
name String?
posts Post[]
}
model Post {
id Int @id @default(autoincrement())
title String
content String?
published Boolean @default(false)
authorId Int
author User @relation(fields: [authorId], references: [id])
}
これにより、User
とPost
の2つのモデルが作成され、それらの間に一対多の関係が設定されます。
2.3. Prisma Clientジェネレーターの設定
次に、以下のコマンドを実行してデータベーステーブルを作成し、Prisma Clientを生成します。
npx prisma migrate dev --name init
2.4. データベースのシード
データベースにサンプルユーザーと投稿を投入するために、シードデータを追加しましょう。
prisma/
ディレクトリにseed.ts
という新しいファイルを作成します。
import { PrismaClient, Prisma } from "../src/generated/prisma/client.js";
const prisma = new PrismaClient();
const userData: Prisma.UserCreateInput[] = [
{
name: "Alice",
email: "alice@prisma.io",
posts: {
create: [
{
title: "Join the Prisma Discord",
content: "https://pris.ly/discord",
published: true,
},
{
title: "Prisma on YouTube",
content: "https://pris.ly/youtube",
},
],
},
},
{
name: "Bob",
email: "bob@prisma.io",
posts: {
create: [
{
title: "Follow Prisma on Twitter",
content: "https://www.twitter.com/prisma",
published: true,
},
],
},
},
];
export async function main() {
for (const u of userData) {
await prisma.user.create({ data: u });
}
}
main();
次に、package.json
を更新して、このスクリプトを実行する方法をPrismaに伝えます。
{
"name": "prisma-solid",
"type": "module",
"scripts": {
"dev": "vinxi dev",
"build": "vinxi build",
"start": "vinxi start"
},
"prisma": {
"seed": "tsx prisma/seed.ts"
}
"dependencies": {
"@prisma/client": "^6.5.0",
"@prisma/extension-accelerate": "^1.3.0",
"@solidjs/start": "^1.1.0",
"solid-js": "^1.9.5",
"vinxi": "^0.5.3"
},
"engines": {
"node": ">=22"
},
"devDependencies": {
"@types/node": "^22.13.11",
"prisma": "^6.5.0",
"tsx": "^4.19.3"
}
}
シードスクリプトを実行します。
npx prisma db seed
そしてPrisma Studioを開いてデータを調べます。
npx prisma studio
3. SolidStartへのPrismaの統合
3.1. Prisma Clientの作成
プロジェクトのルートに、新しいlib
フォルダとその中にprisma.ts
ファイルを作成します。
mkdir -p lib && touch lib/prisma.ts
Prisma Clientインスタンスを作成するために、以下のコードを追加します。
- Prisma Postgres (推奨)
- その他のデータベース
import { PrismaClient } from "../src/generated/prisma/client.js";
import { withAccelerate } from "@prisma/extension-accelerate";
const prisma = new PrismaClient().$extends(withAccelerate());
export default prisma;
import { PrismaClient } from "../src/generated/prisma/client.js";
const prisma = new PrismaClient();
export default prisma;
データベース接続を効率的に管理するため、(例: Prisma Accelerateのような) コネクションプーラーの使用を推奨します。
コネクションプーラーを使用しない場合、長期間稼働する環境ではPrismaClient
をグローバルにインスタンス化することは避けてください。代わりに、データベース接続を使い果たさないように、リクエストごとにクライアントを作成および破棄してください。
3.2. APIルートの作成
次に、APIルートを使用してデータベースからデータをフェッチしましょう。
src/routes/api/users.ts
に新しいファイルを作成します。
import prisma from "../../../lib/prisma";
export async function GET() {
const users = await prisma.user.findMany({
include: {
posts: true,
},
});
return new Response(JSON.stringify(users), {
headers: { "Content-Type": "application/json" },
});
}
3.3. コンポーネントでのデータのフェッチ
app.tsx
ファイルで、createResource
を使用して新しいAPIルートからデータをフェッチします。
import "./app.css";
import { createResource } from "solid-js";
import { User, Post } from "./generated/prisma/client";
type UserWithPosts = User & {
posts: Post[];
};
const fetchUsers = async () => {
const res = await fetch("https://:3000/api/users");
return res.json();
};
export default function App() {
const [users, { mutate, refetch }] = createResource<UserWithPosts[]>(fetchUsers);
return (
<main>
<h1>SolidStart + Prisma</h1>
</main>
);
}
createResource
は、非同期データを管理するためのSolidJSのフックです。読み込み状態とエラー状態を自動的に追跡します。詳細はこちら。
3.4. データの表示
ユーザーとその投稿を表示するには、SolidJSの<For>
コンポーネントを使用します。
import "./app.css";
import { createResource, For } from "solid-js";
import { User, Post } from "./generated/prisma/client";
type UserWithPosts = User & {
posts: Post[];
};
const fetchUsers = async () => {
const res = await fetch("https://:3000/api/users");
return res.json();
};
export default function App() {
const [users, { mutate, refetch }] =
createResource<UserWithPosts[]>(fetchUsers);
return (
<main>
<h1>SolidJS + Prisma</h1>
<For each={users() ?? []}>
{(user) => (
<div>
<h3>{user.name}</h3>
<For each={user.posts}>{(post) => <p>{post.title}</p>}</For>
</div>
)}
</For>
</main>
);
}
<For>
は配列をリアクティブにループ処理します。Reactの.map()
のようなものと考えてください。詳細はこちら
3.5. 読み込み状態とエラー状態の追加
読み込みとエラーの状態を処理するには、SolidJSの<Show>
コンポーネントを使用します。
import "./app.css";
import { createResource, For, Show } from "solid-js";
import { User, Post } from "./generated/prisma/client";
type UserWithPosts = User & {
posts: Post[];
};
const fetchUsers = async () => {
const res = await fetch("https://:3000/api/users");
return res.json();
};
export default function App() {
const [users, { mutate, refetch }] =
createResource<UserWithPosts[]>(fetchUsers);
return (
<main>
<h1>SolidJS + Prisma</h1>
<Show when={!users.loading} fallback={<p>Loading...</p>}>
<Show when={!users.error} fallback={<p>Error loading data</p>}>
<For each={users()}>
{(user) => (
<div>
<h3>{user.name}</h3>
<For each={user.posts}>{(post) => <p>{post.title}</p>}</For>
</div>
)}
</For>
</Show>
</Show>
</main>
);
}
<Show>
は条件付きでコンテンツをレンダリングします。if
文に似ています。詳細はこちら
完了です!Prisma Postgresデータベースに接続されたSolidStartアプリを作成しました。
次のステップ
Prisma Postgresデータベースに接続された動作中のSolidStartアプリができたので、以下のことができます。
- Prismaスキーマをさらに多くのモデルとリレーションシップで拡張する
- 作成/更新/削除のルートとフォームを追加する
- 認証、バリデーション、楽観的更新を探求する
- パフォーマンス向上のため、Prisma Postgresでクエリキャッシュを有効にする
詳細情報
Prismaとのつながり
以下の方法でPrismaの旅を続けましょう 活発なコミュニティに参加しましょう。情報収集し、関わり、他の開発者と協力してください。
- Xでフォロー 発表、ライブイベント、役立つヒントのために。
- Discordに参加 質問したり、コミュニティと交流したり、会話を通じて積極的なサポートを受けたりできます。
- YouTubeを購読 チュートリアル、デモ、ストリームのために。
- GitHubで貢献 リポジトリにスターを付けたり、問題を報告したり、問題に貢献したりして。