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

Prisma ORMをSolidStartで使用する方法

10分

はじめに

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をクリーンアップします。

src/app.tsx
import "./app.css";

export default function App() {
return (
<main>
<h1>SolidStart + Prisma</h1>
</main>
);
}

2. Prismaのインストールと設定

2.1. 依存関係のインストール

Prismaの使用を開始するには、いくつかの依存関係をインストールする必要があります。

npm install prisma tsx --save-dev
npm install @prisma/extension-accelerate @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プロバイダーを使用するように変更します。

prisma/schema.prisma
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])
}

これにより、UserPostの2つのモデルが作成され、それらの間に一対多の関係が設定されます。

2.3. Prisma Clientジェネレーターの設定

次に、以下のコマンドを実行してデータベーステーブルを作成し、Prisma Clientを生成します。

npx prisma migrate dev --name init

2.4. データベースのシード

データベースにサンプルユーザーと投稿を投入するために、シードデータを追加しましょう。

prisma/ディレクトリにseed.tsという新しいファイルを作成します。

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に伝えます。

package.json
{
"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インスタンスを作成するために、以下のコードを追加します。

lib/prisma.ts
import { PrismaClient } from "../src/generated/prisma/client.js";
import { withAccelerate } from "@prisma/extension-accelerate";

const prisma = new PrismaClient().$extends(withAccelerate());

export default prisma;
警告

データベース接続を効率的に管理するため、(例: Prisma Accelerateのような) コネクションプーラーの使用を推奨します。

コネクションプーラーを使用しない場合、長期間稼働する環境ではPrismaClientをグローバルにインスタンス化することは避けてください。代わりに、データベース接続を使い果たさないように、リクエストごとにクライアントを作成および破棄してください。

3.2. APIルートの作成

次に、APIルートを使用してデータベースからデータをフェッチしましょう。

src/routes/api/users.tsに新しいファイルを作成します。

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ルートからデータをフェッチします。

src/app.tsx
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>コンポーネントを使用します。

src/app.tsx
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>コンポーネントを使用します。

src/app.tsx
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で貢献 リポジトリにスターを付けたり、問題を報告したり、問題に貢献したりして。
皆様の参加を心から歓迎し、コミュニティの一員となることを楽しみにしています!

© . All rights reserved.