主要コンテンツにスキップ

AstroでPrisma ORMを使用する方法

15分

はじめに

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を開始するには、いくつかの依存関係をインストールする必要があります

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 Astro Project」のような覚えやすいデータベース名を選択してください。

これにより以下が作成されます。

  • schema.prismaファイルを含むprisma/ディレクトリ
  • DATABASE_URLがすでに設定されている.envファイル

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": "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クライアントをこのように設定します

src/lib/prisma.ts
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;
警告

データベース接続を効率的に管理するために、コネクションプーラー(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ルートを作成します。各ユーザーのPostsincludeフィールドに追加して、必ず含めるようにしてください。

src/pages/api/users.ts
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ルートからデータを取得する

まず、UserPostモデルを組み合わせたUserWithPostsという新しい型を作成します。

src/pages/index.astro
---
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型に設定します。

src/pages/index.astro
---
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型を追加して、ユーザーの名前を表示します。

src/pages/index.astro
---
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型を設定します。

src/pages/index.astro
---
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でエンゲージする リポジトリにスターを付けたり、問題を報告したり、問題に貢献したりしてください。
皆様のご参加を心よりお待ちしております!

© . All rights reserved.