Next.js App RouterとPrisma: セットアップとコネクションプーリング

Table of Contents
モダンNext.jsアーキテクチャシリーズ
Next.js App Routerが導入されたとき、それはフルスタックReact開発における根本的なパラダイムシフトを意味しました。React Server Components(RSC)とPrisma ORMを組み合わせることで、開発者はサーバーコンポーネントから直接データベースをクエリでき、クライアント側のフェッチウォーターフォールをゼロにし、完全なTypeScriptの安全性と、楽なServer Actionミューテーションを実現します。
この包括的なガイドでは、コネクションプーリング、プール枯渇を防ぐためのグローバルシングルトン、型安全なServer Actions、自動化されたデータベースシードスクリプトなど、本番環境に対応したNext.jsとPrismaアプリケーションを構築する方法を探ります。
1. プロジェクトの初期化とPrismaスキーマ
Prismaをインストールし、データベース接続を初期化します。
npm install prisma @prisma/client
npx prisma init
prisma/schema.prisma内にリレーショナルモデルを定義します。
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
model User {
id String @id @default(cuid())
email String @unique
name String?
posts Post[]
createdAt DateTime @default(now())
}
model Post {
id String @id @default(cuid())
title String
content String?
published Boolean @default(false)
authorId String
author User @relation(fields: [authorId], references: [id])
createdAt DateTime @default(now())
}
2. コネクションプールの枯渇防止(グローバルシングルトン)
ローカル開発中、Next.js Fast Refreshはファイル編集ごとにNode.jsモジュールキャッシュをクリアします。個々のルートファイル内でnew PrismaClient()をインスタンス化すると、ホットリロードのたびに新しいデータベース接続が作成され、すぐにPostgreSQLのmax_connectionsエラーが発生します。
lib/prisma.tsに堅牢なシングルトンを作成します。
// lib/prisma.ts
import { PrismaClient } from '@prisma/client'
const prismaClientSingleton = () => {
return new PrismaClient({
log: process.env.NODE_ENV === 'development' ? ['query', 'error', 'warn'] : ['error'],
})
}
declare global {
var prismaGlobal: undefined | ReturnType<typeof prismaClientSingleton>
}
const prisma = globalThis.prismaGlobal ?? prismaClientSingleton()
export default prisma
if (process.env.NODE_ENV !== 'production') globalThis.prismaGlobal = prisma
3. React Server Componentsでの直接データフェッチ
Server Componentsはサーバー上でのみ実行されるため、接続文字列を公開したり、中間APIルートを構築したりすることなく、Prismaを直接クエリできます。
// app/posts/page.tsx
import prisma from '@/lib/prisma'
import Link from 'next/link'
export const revalidate = 3600 // Cache page for 1 hour
export default async function PostsPage() {
const posts = await prisma.post.findMany({
where: { published: true },
include: { author: { select: { name: true, email: true } } },
orderBy: { createdAt: 'desc' },
})
return (
<main className="max-w-4xl mx-auto p-8">
<h1 className="text-3xl font-bold mb-6">Published Articles</h1>
<div className="grid gap-4">
{posts.map((post) => (
<article key={post.id} className="p-5 border rounded-xl shadow-sm">
<h2 className="text-xl font-semibold">{post.title}</h2>
<p className="text-sm text-gray-500">By {post.author.name}</p>
</article>
))}
</div>
</main>
)
}
4. Server Actionsによる型安全なデータミューテーション
データをミューテーションするには、'use server'でServer Actionsを宣言し、キャッシュタグを再検証します。
// app/actions/createPost.ts
'use server'
import prisma from '@/lib/prisma'
import { revalidatePath } from 'next/cache'
import { redirect } from 'next/navigation'
export async function createPost(formData: FormData) {
const title = formData.get('title') as string
const content = formData.get('content') as string
const authorId = formData.get('authorId') as string
if (!title || !authorId) {
throw new Error('Title and Author are required')
}
const post = await prisma.post.create({
data: { title, content, published: true, authorId },
})
revalidatePath('/posts')
redirect(`/posts/${post.id}`)
}
5. データベースの自動シード
開発データベースをシードするには、prisma/seed.tsを作成します。
// prisma/seed.ts
import { PrismaClient } from '@prisma/client'
const prisma = new PrismaClient()
async function main() {
await prisma.post.deleteMany()
await prisma.user.deleteMany()
const user = await prisma.user.create({
data: {
email: 'admin@locionic.com',
name: 'Locionic',
posts: {
create: [
{ title: 'Next.js App Router Architecture', published: true },
{ title: 'Prisma Connection Pooling Guide', published: true },
],
},
},
})
console.log('Database seeded successfully:', user.email)
}
main()
.catch((e) => {
console.error(e)
process.exit(1)
})
.finally(async () => {
await prisma.$disconnect()
})
package.jsonにシードスクリプトの設定を追加します。
"prisma": {
"seed": "ts-node --compiler-options {\"module\":\"CommonJS\"} prisma/seed.ts"
}
npx prisma db seedでシードコマンドを実行します。
Next.js Fast Refreshはファイル変更ごとにモジュールを再構築し、ホットリロードのたびに新しいPrismaClientインスタンスを作成します。クライアントをNode.jsのグローバルオブジェクト(globalThis.prismaGlobal)にアタッチすることで、開発サーバーのライフサイクル中に単一の接続プールインスタンスのみが存在するようにします。
いいえ、Prismaはブラウザのランタイム内では実行できない直接的なTCPデータベースソケット接続を必要とします。Prismaのクエリは、Server Components、Route Handlers、またはServer Actions内でのみ実行してください。
VercelやAWS Lambdaのようなサーバーレスプラットフォームにデプロイする場合、PgBouncer、Neon Serverless Pooling、Supabase Supavisor、またはPrisma Accelerateと?pgbouncer=true&connection_limit=1のようなコネクションプーラーを介して接続します。
package.jsonにprisma/seed.tsを指すprisma.seedコマンドを定義し、npx prisma db seedを実行してデモデータを決定論的に投入します。
こちらもおすすめ
Free In-Browser Developer Tools
Clean AI CLI logs, build cron expressions, decode JWTs, and calculate chmod permissions offline.
Related Articles

Next.jsにおけるReactハイドレーションエラー418の修正:テキスト不一致と拡張機能(2026年版)
Next.jsのハイドレーションエラーを解決する2026年版完全ガイドで、Minified React Error #418、Error #423、Text Content Mismatch、window/localStorageのSSRバグをコピペコードとライブデバッガーで修正しましょう。
Read more
Next.js、Contentlayer、Git Submodulesでポートフォリオを構築した方法
locionic.comのアーキテクチャを解説:Next.js App Router、Contentlayerによる型安全なMDX、RSCペイロード最適化、自動内部リンクメッシュ。
Read more
Next.jsにおけるsuppressHydrationWarning: 安全な利用法とデバッグの完全ガイド
Next.jsのsuppressHydrationWarningについて、安全な利用法とデバッグ方法を実証済みの本番環境での例を交えて網羅的に解説する包括的なガイドです。
Read more