AstroでPrisma ORMを使用する方法
はじめに
Prisma ORMはタイプセーフなデータベースアクセスを提供し、Astroはパフォーマンスのために構築されています。Prisma Postgresと組み合わせることで、コールドスタートゼロでエンドツーエンドの速度を実現する、高速でコンテンツファーストなスタックが得られます。
このガイドでは、Prisma ORMをPrisma PostgresデータベースとAstroプロジェクトにゼロから統合する方法を学びます。このガイドの完全な例はGitHubで確認できます。
前提条件
1. プロジェクトのセットアップ
新しいAstroプロジェクトを作成する
npx create-astro@latest
- 新しいプロジェクトはどこに作成しますか?
astro-prisma
- 新しいプロジェクトをどのように開始しますか?
最小限の(空の)テンプレートを使用する
- 依存関係をインストールしますか? (推奨)
はい
- 新しいgitリポジトリを初期化しますか? (任意)
はい
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 Astro Project」のような覚えやすいデータベース名を選択してください。
これにより以下が作成されます。
schema.prisma
ファイルを含むprisma/
ディレクトリDATABASE_URL
がすでに設定されている.env
ファイル
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": "extinct-eclipse-minimal",
"type": "module",
"version": "0.0.1",
"scripts": {
"dev": "astro dev",
"build": "astro build",
"preview": "astro preview",
"astro": "astro"
},
"prisma": {
"seed": "tsx prisma/seed.ts"
},
"dependencies": {
"@prisma/client": "^6.7.0",
"@prisma/extension-accelerate": "^1.3.0",
"astro": "^5.7.10"
},
"devDependencies": {
"prisma": "^6.7.0",
"tsx": "^4.19.4"
}
}
シードスクリプトを実行する
npx prisma db seed
そしてPrisma Studioを開いてデータを検査する
npx prisma studio
3. PrismaをAstroに統合する
3.1. Prismaクライアントを作成する
/src
内に、lib
ディレクトリと、その中にprisma.ts
ファイルを作成します。このファイルは、Prisma Clientインスタンスを作成し、エクスポートするために使用されます。
mkdir src/lib
touch src/lib/prisma.ts
Prismaクライアントをこのように設定します
- Prisma Postgres (推奨)
- その他のデータベース
import { PrismaClient } from "../generated/prisma/client.js";
import { withAccelerate } from "@prisma/extension-accelerate";
const prisma = new PrismaClient({
datasourceUrl: import.meta.env.DATABASE_URL,
}).$extends(withAccelerate());
export default prisma;
import { PrismaClient } from "../generated/prisma/client.js";
const prisma = new PrismaClient({
datasourceUrl: import.meta.env.DATABASE_URL,
})
export default prisma;
データベース接続を効率的に管理するために、コネクションプーラー(Prisma Accelerateなど)を使用することを推奨します。
コネクションプーラーを使用しない場合、長時間稼働する環境でPrismaClient
をグローバルにインスタンス化することは避けてください。代わりに、データベース接続の枯渇を防ぐために、リクエストごとにクライアントを作成し、破棄してください。
3.2. APIルートの作成
APIルートは、Astroアプリでデータベースからデータを取得する最良の方法です。
src/pages
ディレクトリにapi/users.ts
という新しいファイルを作成します。
mkdir src/pages/api
touch src/pages/api/users.ts
次に、データベースからUsers
データをフェッチするGETルートを作成します。各ユーザーのPosts
をinclude
フィールドに追加して、必ず含めるようにしてください。
import type { APIRoute } from "astro";
import prisma from "../../lib/prisma";
export const GET: APIRoute = async () => {
const users = await prisma.user.findMany({
include: { posts: true },
});
return new Response(JSON.stringify(users), {
headers: { "Content-Type": "application/json" },
});
};
次に、index.astro
ファイルからこのルートを呼び出して表示します。
3.3. APIルートからデータを取得する
まず、User
とPost
モデルを組み合わせたUserWithPosts
という新しい型を作成します。
---
import type { User, Post } from "../generated/prisma/client.js";
type UserWithPosts = User & { posts: Post[] };
---
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<meta name="viewport" content="width=device-width" />
<meta name="generator" content={Astro.generator} />
<title>Astro</title>
</head>
<body>
<h1>Astro</h1>
</body>
</html>
APIルートからデータを取得し、その型を今作成したUserWithPosts
型に設定します。
---
import type { User, Post } from "../generated/prisma/client.js";
type UserWithPosts = User & { posts: Post[] };
const response = await fetch("https://:4321/api/users");
const users: UserWithPosts[] = await response.json();
---
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<meta name="viewport" content="width=device-width" />
<meta name="generator" content={Astro.generator} />
<title>Astro</title>
</head>
<body>
<h1>Astro</h1>
</body>
</html>
3.4. データを表示する
フロントマターの変数がファイル全体で利用可能になったので、ユーザーのリストを表示できます。
<h1>
タグのすぐ下に、users
配列をマップし、ユーザーにUserWithPosts
型を追加して、ユーザーの名前を表示します。
---
import type { User, Post } from "../generated/prisma/client.js";
type UserWithPosts = User & { posts: Post[] };
const response = await fetch("https://:4321/api/users");
const users: UserWithPosts[] = await response.json();
---
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<meta name="viewport" content="width=device-width" />
<meta name="generator" content={Astro.generator} />
<title>Astro</title>
</head>
<body>
<h1>Astro + Prisma</h1>
{users.map((user: UserWithPosts) => (
<li>
<h2>{user.name}</h2>
</li>
))}
</body>
</html>
最後に、各User
の下にPosts
を表示し、Post
型を設定します。
---
import type { User, Post } from "../generated/prisma/client.js";
type UserWithPosts = User & { posts: Post[] };
const response = await fetch("https://:4321/api/users");
const users: UserWithPosts[] = await response.json();
---
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<meta name="viewport" content="width=device-width" />
<meta name="generator" content={Astro.generator} />
<title>Astro</title>
</head>
<body>
<h1>Astro + Prisma</h1>
<ul>
{users.map((user: UserWithPosts) => (
<li>
<h2>{user.name}</h2>
<ul>
{user.posts.map((post: Post) => (
<li>{post.title}</li>
))}
</ul>
</li>
))}
</ul>
</body>
</html>
完了です!Prisma Postgresデータベースに接続されたPrismaを使用したAstroアプリを構築しました。以下に、さらに探索するための次のステップと、プロジェクトを拡張するのに役立つリソースを示します。
次のステップ
Prisma Postgresデータベースに接続されたAstroアプリが動作するようになったので、以下のことができます。
- Prismaスキーマをさらに多くのモデルやリレーションシップで拡張する
- 作成/更新/削除ルートとフォームを追加する
- 認証とバリデーションを探索する
- パフォーマンス向上のため、Prisma Postgresでクエリキャッシュを有効にする
詳細情報
Prismaとのつながり
Prismaの旅を続けるには、以下とつながりましょう。 アクティブなコミュニティ。情報を入手し、参加し、他の開発者と協力しましょう。
- Xでフォローする アナウンス、ライブイベント、役立つヒントを入手できます。
- Discordに参加する 質問をしたり、コミュニティと話したり、会話を通じてアクティブなサポートを受けたりできます。
- YouTubeを購読する チュートリアル、デモ、ライブ配信を視聴できます。
- GitHubでエンゲージする リポジトリにスターを付けたり、問題を報告したり、問題に貢献したりしてください。