2023. 12. 4. 09:28ㆍ프레임워크/Nest.js
1. Prisma 란?
Prisma Client : NodeJS 와 TypeScript 전용 Type Safe 및 자동 생성 쿼리 빌더
Prisma Migrate : Migration system, 데이터 모델링
Prisma Studio : GUI 를 통해 DB 를 수정할 수 있는 기능
-Prisma Docs-
2. 왜 Prisma 를 사용하는가
Prisma 의 목적은 데이터베이스 작업 시 개발자의 생산성을 높이는 것이다.
- 관계형 데이터를 매핑하는 것 대신 객체를 사용
- 복잡한 모델 객체를 피하기 위해 클래스가 아닌 쿼리를 사용
- 데이터베이스 및 어플리케이션 모델을 위한 Single source of Truth 이론(정보의 중복, 비적 합성 등의 문제를 해결하기 위한 이론)
- 흔한 함정과 안티패턴을 막기 위한 단단단한 제약 조건
- 올바른 것을 쉽게 만드는 추상화
- 컴파일 시 유효성 검사를 할 수 있는 Type Safe 데이터베이스 쿼리
- 단순 노동을 줄일 수 있도록 하여(Boilerplate Code) 개발자 들이 어플리케이션에 집중할 수 있다.
rds 와 prisma 를 사용하면서 간단한 게시판 및 댓글 API 를 만들어 볼 생각이다.
3. ERD
4. RDS 생성
https://muyeon95.tistory.com/196
5. 프로젝트 생성
nest new rds-prisma-poc
6. prisma 설치
npm install prisma --save-dev
npm i @prisma/client
npx prisma
7. prisma initialize
npx prisma init
8. .env URL 변경
DATABASE_URL 을 Mysql 관련 설정으로 변경
DATABASE_URL="mysql://[마스터 사용자 이름]:[RDS 암호]@[엔드포인드]:3306/[스키마명]"
.env 설정은 아래링크를 참고하면 된다.
https://muyeon95.tistory.com/287
9. Prisma Schema
schema.prisma 파일은 Prisma 설정에 대한 파일이다.
크게 아래처럼 나눌 수 있다.
- Generators : Prisma Client 를 기반으로 생성되어야 하는 클라이언트를 정의(어떤 부분을 DB 와 연결할지, 다수 DB 연결도 가능)
- Datasource : Prisma 가 연결해야 할 DB 에 대한 정보를 정의(prisma client 명령어 사용시 생성될 내용을 정의)
- Data Model : 데이터 모델(테이블)을 정의
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "mysql"
url = env("DATABASE_URL")
}
model Review {
reviewId Int @id @default(autoincrement())
title String
content String
starRating Int
author String
password String
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
comments Comment[]
}
model Comment {
commentId Int @id @default(autoincrement())
content String
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
review Review @relation(fields: [reviewId], references: [reviewId])
reviewId Int @unique
}
관계 설정 : https://www.prisma.io/docs/concepts/components/prisma-schema/relations
10. Migrate
명령어를 통해 Prisma Schema 에서 정의한 설정과 모델을 바탕으로 Migrate 할 수 있다.
Migrate란? : 추가, 변경, 삭제 등을 진행한 Model 을 데이터베이스에 전송하여 반영하는 것
npx prisma migrate dev --name <HISTORY-NAME>
HISTORY-NAME 에 마이그레이션시 남길 History 명을 입력하면 된다.
명령을 수행하면 Model 에 대한 내용이 DB 에 마이그레이션되고, prisma/migrations 경로에 히스토리가 남는 것을 확인 할 수 있다.
npx prisma migrate dev --name migration
데이터베이스와 모델을 마이그레이션을 수행하기 전에 수정이 필요한 상황이라면?
- 중요한 리펙토링
- 필드의 이름을 변경
- 관계의 방향을 수정
- Prisma Schema 언어로 나타낼 수 없는 기능을 추가하고자 할 때
이런 상황에는 --create-only 명령어를 추가하면 된다.
npx prisma migrate dev --create-only
옵션을 추가해 마이그레이션을 진행하면, 변경 내용이 DB 에 즉시 반영되지 않고 히스토리만 남는다.
최종적으로 수정된 Schema 로 마이그레이션 할 때는 아래 명령어를 실행하면 된다.
npx prisma migrate dev
11. Prisma Client 로 DB 조작
DB 를 제어, 조작하기 위해서는 Prisma Client 가 필요하다.
npm i @prisma/client
Prisma Client 생성
npx prisma generate
명령어가 실행되면 Prisma 는 Model 에 대한 스키마를 읽고 Prisma Client 에 반영한다.
Prisma Schema 가 변경된다면 generate 명령어를 통해 Prisma Client 를 업데이트 해줘야 한다.
12. CRUD 수행
https://www.prisma.io/docs/concepts/components/prisma-client/crud
뼈대
import { Injectable, OnModuleInit } from '@nestjs/common';
import { PrismaClient } from '@prisma/client';
@Injectable()
export class ReviewsRepository extends PrismaClient implements OnModuleInit {
async onModuleInit() {
await this.$connect();
}
}
create
async createReview(body: ReviewRequestDto) {
return await this.review.create({
data: {
title: body.title,
content: body.content,
starRating: body.starRating,
author: body.author,
password: body.password,
},
});
}
createMany
async createManyReview(body: ReviewRequestDto) {
return await this.review.createMany({
data: [
{
title: body.title,
content: body.content,
starRating: body.starRating,
author: body.author,
password: body.password,
},
{
title: body.title,
content: body.content,
starRating: body.starRating,
author: body.author,
password: body.password,
},
{
title: body.title,
content: body.content,
starRating: body.starRating,
author: body.author,
password: body.password,
},
],
});
}
read : 상세 조회
async findOneReview(reviewId: number) {
const parseId = Number(reviewId);
return await this.review.findUnique({
where: {
reviewId: parseId,
},
});
}
update
update(), updateMany() 메서드를 사용해 데이터를 업데이트 할 수 있다.
updateMany() 도 createMany() 와 동일하게 return 값이 count 로만 이루어져 있다.
async updateReview(reviewId: number, body: ReviewRequestDto) {
const parseId = Number(reviewId);
return await this.review.update({
where: {
reviewId: parseId,
},
data: {
title: body.title,
content: body.content,
starRating: body.starRating,
author: body.author,
password: body.password,
},
});
}
delete
delete(), deleteMany() 메서드를 사용해 데이터를 삭제할 수 있다.
deleteMany() 도 createMany() 와 동일하게 return 값이 count 로만 이루어져 있다.
async deleteReview(reviewId: number) {
const parseId = Number(reviewId);
return await this.review.delete({
where: {
reviewId: parseId,
},
});
}
이후 comment 및 에러처리 까지 하면 완성!
참고링크
https://choidr.tistory.com/entry/NestJS-Prisma-CRUD
https://www.prisma.io/docs/concepts/components/prisma-client/crud#read
https://docs.nestjs.com/recipes/prisma#set-up-prisma
https://sdy-study.tistory.com/79
'프레임워크 > Nest.js' 카테고리의 다른 글
Dependency Injection / Inversion of Control [의존성 주입 / 제어의 역전] [NestJS] (0) | 2023.12.13 |
---|---|
NestJS 요청 라이프 사이클 (NestJS Request Lifecycle) (0) | 2023.12.11 |
Mongoose 사용하기 [Nest.js] (0) | 2023.12.03 |
Nest.js 미들웨어 (logger 미들웨어) (1) | 2023.12.02 |
Nest.js 환경변수 설정하기 with ConfigModule [Nest.js] (0) | 2023.12.02 |