SolidStart で Prisma ORM を使用する方法
はじめに
Prisma ORM は、タイプセーフなクエリとスムーズな開発者エクスペリエンスにより、データベースアクセスを効率化します。SolidJS でリアクティブな Web アプリを構築するための最新フレームワークである SolidStart は、Prisma および Postgres と組み合わせることで、クリーンでスケーラブルなフルスタックアーキテクチャを作成できます。
このガイドでは、SolidStart プロジェクトで Prisma Postgres データベースと Prisma ORM をゼロから統合する方法を学びます。このガイドの完全な例は、GitHubにあります。
前提条件
始める前に、以下がインストールされていることを確認してください。
- Node.js 18+ がインストールされていること
ステップ 1: SolidStart プロジェクトのセットアップ
まず、新しい SolidStart アプリケーションを作成します。ターミナルで、次を実行します。
npm init solid@latest
プロンプトが表示されたら、次のオプションを使用します。
- プロジェクト名:
my-solid-prisma-app
(または任意の名前) - これは SolidStart プロジェクトですか:
yes
- テンプレート:
bare
- TypeScript を使用しますか:
yes
次に、新しいプロジェクトに移動し、依存関係をインストールして、開発サーバーを起動します。
cd my-solid-prisma-app
npm install
npm run dev
開発サーバーが実行されたら、ブラウザで http://localhost:3000
を開きます。SolidStart のウェルカム画面が表示されるはずです。
app.tsx
ファイルを編集してヘッダーを置き換えることで、デフォルトの UI をクリーンアップしましょう。
import { createSignal } from "solid-js";
import "./app.css";
export default function App() {
const [count, setCount] = createSignal(0);
return (
<main>
<h1>SolidStart + Prisma</h1>
<h1>Hello world!</h1>
<button class="increment" onClick={() => setCount(count() + 1)} type="button">
Clicks: {count()}
</button>
<p>
Visit{" "}
<a href="https://start.solidjs.com" target="_blank">
start.solidjs.com
</a>{" "}
to learn how to build SolidStart apps.
</p>
</main>
);
}
app.tsx
ファイルは次のようになります。
import "./app.css";
export default function App() {
return (
<main>
<h1>SolidStart + Prisma</h1>
</main>
);
}
ステップ 2: Prisma のインストールと初期化
Prisma を使い始めるには、いくつかの依存関係をインストールする必要があります。
npm install prisma @prisma/client --save-dev
npm install tsx --save-dev
npm install @prisma/extension-accelerate
Prisma Postgres データベースを使用していない場合は、@prisma/extension-accelerate
をスキップできます。
インストールしたら、プロジェクトで Prisma を初期化します。
npx prisma init --db --output ../src/generated/prisma
これにより、以下が作成されます。
prisma/
ディレクトリとschema.prisma
ファイルDATABASE_URL
がすでに設定された.env
ファイル
ステップ 2.1: Prisma Schema の定義
prisma/schema.prisma
ファイルを開き、次のモデルを追加し、ジェネレーターを prisma-client
プロバイダーを使用するように変更します。
generator client {
provider = "prisma-client"
provider = "prisma-client-js"
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 つのモデルが作成され、それらの間に一対多のリレーションシップが設定されます。
次に、次のコマンドを実行してデータベーステーブルを作成し、Prisma Client を生成します。
npx prisma migrate dev --name init
ステップ 2.2: データベースのシード
サンプルユーザーと投稿でデータベースをpopulateするために、いくつかのシードデータを追加しましょう。
prisma/
ディレクトリに seed.ts
という名前の新しいファイルを作成します。
import { PrismaClient, Prisma } from "../src/generated/prisma";
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 に指示します。
"prisma": {
"seed": "tsx prisma/seed.ts"
}
シードスクリプトを実行します。
npx prisma db seed
Prisma Studio を開いてデータを確認します。
npx prisma studio
ステップ 3: アプリケーションで Prisma Client を使用する
ステップ 3.1: Prisma Client の作成
プロジェクトのルートに、新しい lib
フォルダと、その中に prisma.ts
ファイルを作成します。
mkdir -p lib && touch lib/prisma.ts
次のコードを追加して、Prisma Client インスタンスを作成します。
import { PrismaClient } from "../src/generated/prisma";
import { withAccelerate } from "@prisma/extension-accelerate";
const prisma = new PrismaClient().$extends(withAccelerate());
export default prisma;
Prisma Postgres を使用していない場合は、.$extends(withAccelerate())
を削除します。
ステップ 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" },
});
}
ステップ 4: コンポーネントでデータをフェッチする
app.tsx
ファイルで、createResource
を使用して新しい API ルートからデータをフェッチします。
import "./app.css";
import { createResource } from "solid-js";
import { User, Post } from "@prisma/client";
type UserWithPosts = User & {
posts: Post[];
};
const fetchUsers = async () => {
const res = await fetch("http://localhost: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 フックです。ロード状態とエラー状態を自動的に追跡します。詳細はこちら。
ステップ 5: データの表示
ユーザーとその投稿を表示するには、SolidJS の <For>
コンポーネントを使用します。
import "./app.css";
import { createResource, For } from "solid-js";
import { User, Post } from "@prisma/client";
type UserWithPosts = User & {
posts: Post[];
};
const fetchUsers = async () => {
const res = await fetch("http://localhost: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()
のようなものと考えてください。詳細はこちら
ステップ 6: ロード状態とエラー状態の追加
SolidJS の <Show>
コンポーネントを使用して、ロード状態とエラー状態を処理します。
import "./app.css";
import { createResource, For, Show } from "solid-js";
import { User, Post } from "@prisma/client";
type UserWithPosts = User & {
posts: Post[];
};
const fetchUsers = async () => {
const res = await fetch("http://localhost: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 スキーマをより多くのモデルとリレーションシップで拡張する
- create/update/delete ルートとフォームを追加する
- 認証、バリデーション、および楽観的アップデートを探索する
詳細情報
Prisma とのつながりを保ちましょう
以下とつながることで Prisma の旅を続けましょう アクティブなコミュニティ。最新情報を入手し、参加し、他の開発者と協力しましょう。
- X でフォローしてください お知らせ、ライブイベント、役立つヒント。
- Discord に参加してください 質問をしたり、コミュニティと話したり、会話を通じてアクティブなサポートを受けましょう。
- YouTube で購読してください チュートリアル、デモ、ストリーム。
- GitHub でエンゲージしましょう リポジトリにスターを付けたり、問題を報告したり、問題に貢献したりします。