nestjs prisma 사용해보기 with AWS RDS

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 의 목적은 데이터베이스 작업 시 개발자의 생산성을 높이는 것이다.

 

  1. 관계형 데이터를 매핑하는 것 대신 객체를 사용
  2. 복잡한 모델 객체를 피하기 위해 클래스가 아닌 쿼리를 사용
  3. 데이터베이스 및 어플리케이션 모델을 위한 Single source of Truth 이론(정보의 중복, 비적 합성 등의 문제를 해결하기 위한 이론)
  4. 흔한 함정과 안티패턴을 막기 위한 단단단한 제약 조건
  5. 올바른 것을 쉽게 만드는 추상화
  6. 컴파일 시 유효성 검사를 할 수 있는 Type Safe 데이터베이스 쿼리
  7. 단순 노동을 줄일 수 있도록 하여(Boilerplate Code) 개발자 들이 어플리케이션에 집중할 수 있다.

 

rds 와 prisma 를 사용하면서 간단한 게시판 및 댓글 API 를 만들어 볼 생각이다.

 

 


3. ERD

 

 


4. RDS 생성

https://muyeon95.tistory.com/196

 

RDS 사용하기 [ with mysql ]

https://ap-northeast-2.console.aws.amazon.com/console/home?nc2=h_ct&src=header-signin®ion=ap-northeast-2 https://ap-northeast-2.console.aws.amazon.com/console/home?nc2=h_ct®ion=ap-northeast-2&src=header-signin ap-northeast-2.console.aws.amazon.com 위

muyeon95.tistory.com

 

 


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

 

Nest.js 환경변수 설정하기 with ConfigModule [Nest.js]

간단하게 PORT 로만 해보도록 하겠다. 프로젝트에 .env 파일 생성 // .env PORT=3000 @nestjs/config 설치 npm i @nestjs/config app.module.ts 에 ConfigModule 을 추가 모듈에서 사용하기 위해 app.module.ts 에 아래처럼 추

muyeon95.tistory.com

 


9. Prisma Schema

 

schema.prisma 파일은 Prisma 설정에 대한 파일이다.

크게 아래처럼 나눌 수 있다.

 

  1. Generators : Prisma Client 를 기반으로 생성되어야 하는 클라이언트를 정의(어떤 부분을 DB 와 연결할지, 다수 DB 연결도 가능)
  2. Datasource : Prisma 가 연결해야 할 DB 에 대한 정보를 정의(prisma client 명령어 사용시 생성될 내용을 정의)
  3. 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

 

Relations (Reference)

A relation is a connection between two models in the Prisma schema. This page explains how you can define one-to-one, one-to-many and many-to-many relations in Prisma.

www.prisma.io

 

 


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

 

CRUD (Reference)

How to perform CRUD with Prisma Client.

www.prisma.io

 

뼈대

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

 

NestJS, Prisma - CRUD

Prisma, Mysql 시작하기 Prisma 란? 공식 홈페이지 에서 확인해보면 차세대 오픈 소스 ORM 으로 아래와 같은 구성으로 이뤄져있다고 합니다. Prisma Client : NodeJS 와 TypeScript 전용 Type Safe 및 자동 생성 쿼리

choidr.tistory.com

https://www.prisma.io/docs/concepts/components/prisma-client/crud#read

 

CRUD (Reference)

How to perform CRUD with Prisma Client.

www.prisma.io

https://docs.nestjs.com/recipes/prisma#set-up-prisma

 

Documentation | NestJS - A progressive Node.js framework

Nest is a framework for building efficient, scalable Node.js server-side applications. It uses progressive JavaScript, is built with TypeScript and combines elements of OOP (Object Oriented Programming), FP (Functional Programming), and FRP (Functional Rea

docs.nestjs.com

https://sdy-study.tistory.com/79

 

schema.prisma 정리

# 개요 schema.prisma 파일엔 크게 3가지 부분으로 나뉜다 1. Data Source : Data Source 부분은 어떤 DB 와 연결할것인지 설정하는 부분이다. prisma 에서 지원하는 DB 는 PostgreSQL, MySQL, SQLite 가 있으며 이런식으

sdy-study.tistory.com