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

SolidStart で Prisma ORM を使用する方法

10 分

はじめに

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

src/app.tsx
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 ファイルは次のようになります。

src/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 プロバイダーを使用するように変更します。

prisma/schema.prisma
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 という名前の新しいファイルを作成します。

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 に指示します。

package.json
"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 インスタンスを作成します。

lib/prisma.ts
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 に新しいファイルを作成します。

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

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

src/app.tsx
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> コンポーネントを使用して、ロード状態とエラー状態を処理します。

src/app.tsx
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 の旅を続けましょう アクティブなコミュニティ。最新情報を入手し、参加し、他の開発者と協力しましょう。

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