この記事では、NestJSでのPrismaの基本的なセットアップから高度なデータベース操作まで、一通りを網羅的に解説します。これからNestJSとPrismaを使ってプロジェクトを始める方、または既存のプロジェクトにPrismaを導入したい方にとって参考になるかと思います。
Prismaの基本的な概要
Prismaとは何か?
Prismaは、データベースへのアクセスと操作を簡単かつ効率的に行うためのオープンソースのORM(Object-Relational Mapping)ツールです。TypeScriptやJavaScriptで書かれたアプリケーションに最適化されており、SQLやNoSQLデータベースとの連携が容易です。
Prismaが選ばれる理由
Prismaが多くの開発者に選ばれる理由はいくつかありますが、主な点は以下の通りです。
型安全
PrismaはTypeScriptと密接に統合されているため、コンパイル時にエラーをキャッチできます。
高度なクエリ
複雑なクエリやリレーショナルデータの操作も簡単に行えます。
コードの簡潔性
Prismaを使用することで、データベース操作に関するコードが簡潔になり、メンテナンスも容易です。
NestJSとPrismaの基本的なセットアップ
NestJSプロジェクトの初期設定
NestJSのインストール
NestJSはNode.jsのフレームワークであり、npmを使用して簡単にインストールできます。
npm i -g @nestjs/cli
プロジェクトの作成
新しいNestJSプロジェクトを作成するには、以下のコマンドを実行します。
nest new your_project_name
Prismaのインストールと設定
Prisma CLIのインストール
Prismaをインストールすることで、Prismaの各種コマンドを利用できます。
npm install prisma --save-dev
Prismaスキーマの設定
prisma/schema.prisma
ファイルを作成し、データベースのスキーマを定義します。
datasource db {
provider = "sqlite"
url = env("DATABASE_URL")
}
generator client {
provider = "prisma-client-js"
}
model User {
id Int @default(autoincrement()) @id
name String
email String @unique
}
マイグレーション
下記コマンドでマグレーションを実行します。
npx prisma migrate dev --name init
するとmigrationsディレクトリとその配下にマイグレーションファイルが生成されます。
Prisma Client
Prisma Clientは、Prismaモデル定義から生成されるタイプセーフのデータベースクライアントです。このアプローチにより、Prisma Clientはモデルに合わせたCRUD操作を公開できます。
下記コマンドでインストールします。
npm install @prisma/client
データベース操作: Prismaを使ったCRUD処理
PrismaServiceの作成
PrismaClientのインスタンス化とデータベースへの接続を行うためのPrismaServiceを作成します。
import { Injectable, OnModuleInit } from '@nestjs/common';
import { PrismaClient } from '@prisma/client';
@Injectable()
export class PrismaService extends PrismaClient implements OnModuleInit {
async onModuleInit() {
await this.$connect();
}
}
基本的なCRUD操作(作成、読み取り、更新、削除)
Prismaを使用して、基本的なCRUD操作を以下のように行えます。
作成(Create)
import { Injectable } from '@nestjs/common';
import { PrismaService } from './prisma.service';
import { User, Prisma } from '@prisma/client';
@Injectable()
export class UserService {
constructor(private prisma: PrismaService) {}
async create(data: { name: string; email: string }): Promise<User> {
return this.prisma.user.create({ data });
}
}
読み取り(Read)
import { Injectable } from '@nestjs/common';
import { PrismaService } from './prisma.service';
import { User, Prisma } from '@prisma/client';
@Injectable()
export class UserService {
constructor(private prisma: PrismaService) {}
async user(id: number): Promise<User | null> {
return this.prisma.user.findUnique({
where: { id }
});
}
}
更新(Update)
import { Injectable } from '@nestjs/common';
import { PrismaService } from './prisma.service';
import { User, Prisma } from '@prisma/client';
@Injectable()
export class UserService {
constructor(private prisma: PrismaService) {}
async update(id: number, data: { name: string; email: string }): Promise<User> {
return this.prisma.user.update({ where: { id }, data });
}
}
削除(Delete)
import { Injectable } from '@nestjs/common';
import { PrismaService } from './prisma.service';
import { User, Prisma } from '@prisma/client';
@Injectable()
export class UserService {
constructor(private prisma: PrismaService) {}
async delete(id: number): Promise<User> {
return this.prisma.user.delete({ where: { id } });
}
}
リレーショナルデータの操作
リレーションの設定
Prismaスキーマにリレーションを設定する例は以下の通りです。
model Post {
id Int @id @default(autoincrement())
title String
author User @relation(fields: [authorId], references: [id])
authorId Int
}
リレーショナルデータの操作
リレーショナルデータを操作するためのサンプルコードです。
import { Injectable } from '@nestjs/common';
import { PrismaService } from './prisma.service';
import { Post, Prisma } from '@prisma/client';
@Injectable()
export class PostService {
constructor(private prisma: PrismaService) {}
async create(title: string, authorId: int): Promise<Post> {
return this.prisma.post.create({
data: {
title,
author: {
connect: { id: authorId },
},
},
});
}
}
トランザクションの管理
Prismaでは、$transaction
メソッドを使用してトランザクションを管理できます。
await prisma.$transaction([
prisma.user.create({ data: { name: 'Alice' } }),
prisma.user.create({ data: { name: 'Bob' } }),
]);
まとめ
NestJSとPrismaを組み合わせることで、型安全かつ効率的なデータベース操作が可能になります。また、高度なリレーショナルデータの操作やトランザクションの管理も容易に行えます。