-
[TIL] 스파르타) Node.js 숙련주차 강의 수강 (AWS RDS, Prisma)TIL-sparta 2024. 5. 20. 20:53
> Node.js 숙련주차 강의를 1-1 부터 1-8 까지 (강의 노트 1주차 3.1~3.4, 하단 링크 참고) 수강하고 핵심 내용을 정리해보았다. PrismaClient를 이용한 query building에 대해서는 추후 프로젝트에서 직접 사용해보고 TIL을 작성하기로 한다.
학습 키워드: aws, RDS, Node.js, prisma, @prisma/client, dotenv, dotenv-expand
1. Setup AWS RDS
1) What is it?:
Amazon AWS에서 제공하는 RDS(Relational Database Service)로, 사용자가 직접 RDB프로그램을 설치하지 않고 AWS 콘솔에서 인스턴스를 생성하여 공간 및 자원을 할당받아 관리할 수 있는 서비스다. 아래 8가지의 엔진 옵션을 제공한다.
2) How does it work?:
AWS console에서 RDS를 검색하여 RDS 콘솔로 진입하면 Create Database라고 적힌 주황색 버튼이 있다. 이 버튼을 누르면 새 DB 인스턴스를 생성할 수 있다.
인스턴스 생성으로 진입하면 가장 먼저 보이는 옵션인데, 좌측의 Standard create를 이용하여 여러가지 설정을 해줄 수도 있지만, 복잡한 설정에 익숙하지 않거나 기본 설정을 이용하고 싶은 유저를 위한 Easy create 모드 또한 존재한다. Easy create 모드를 클릭하면 설정할 내용이 Configuration 항목으로 통합되어 확 줄어드는데, 선택할 수 있는 엔진 옵션에서 IBM Db2가 사라진 것을 볼 수 있다. Db2를 사용해야 한다면 Standard create를 사용하자. 새롭게 발제될 프로젝트에서는 MySQL을 사용할 예정이므로 MySQL을 선택해준다. Standard create를 선택했다면 아래에서 사용할 MySQL 버전을 선택할 수도 있다.
바로 아래에 DB instance size 옵션이 있는데, 실제 서비스가 아니므로 요금이 책정되지 않는 Free tier를 선택해준다.
마지막으로 사용할 DB의 이름, DB의 master 권한이 부여된 user이름 및 비밀번호를 설정할 수 있다. 비밀번호를 임의로 설정해줘도 되지만, 비밀번호 입력란 바로 위에 있는 Auto generate password 체크박스를 체크하여 aws에게 비밀번호 생성을 위임할 수 있다.
체크박스 아래의 파란색 박스에서는 View credential details를 통해서 생성된 비밀번호를 확인할 수 있다고 되어있다.
Create Database 버튼을 눌러 생성을 진행하면 콘솔 상단에 파란색(완료 이후 녹색으로 바뀜) 배너가 생성되면서 DB 생성 절차를 진행한다. 배너에 위치한 View connection details 버튼을 누르면 자동 생성된 비밀번호를 조회할 수 있다. 공식 문서의 'DB 인스턴스 생성'란 14번 항목에 따르면, 마스터 암호를 다시 볼 수는 없다고 하니, 만약 기록 해두지 않고 배너를 닫았다면 콘솔에서 reset 절차를 밟아서 새로운 비밀번호를 설정 해줘야한다.
비밀번호 reset 방법: 콘솔에서 DB 인스턴스 페이지로 이동해보면 우측 상단에 Modify 버튼이 있다. 버튼을 클릭하면 앞서 진행했던 인스턴스 설정 페이지로 이동하는데, 여기서 다시 한 번 비밀번호를 설정해주면 된다. Auto generate를 선택한 경우 Continue 이후의 페이지에서 출력되는 비밀번호를 복사해서 .env 설정 파일에 보관해두자.
Easy Create 모드로 생성을 했다면 마지막으로 한 가지 설정을 더 해줘야한다. 위에서 처럼 Modify 버튼을 눌러서 설정 변경 페이지로 진입한 뒤 Conectivity 항목에서 만들어둔 Security Group을 선택해주고, 아래에 있는 Additional configuration을 눌러서 Publicly accessible을 설정 해줘야만 DB 접근이 가능해진다. Security Group의 경우 미리 생성해 둔 그룹이 없다면 링크에 진입해서 우측 상단의 주황색 Create security group 버튼을 눌러 Inbound와 Outbound 설정을 해주면 된다. Inbound 설정의 경우 선택한 SQL 엔진이 사용하는 port 번호에 My IP를 허용해주고 Outbound 설정은 All trafic, Any IP로 설정해주면 된다.
3) Why use it?:
데이터베이스의 관리, 설정, 운영 및 확장을 aws RDS에 위임하면 따로 DB서버 장비를 구비하고 프로그램을 설치하고 일일이 설정하는 등 비용도 크고 번거롭기까지 한 작업을 건너뛸 수 있기 때문에 개발자가 DB의 사용에만 집중할 수 있는 환경을 조성할 수 있다.
2. Prisma
1) What is it?:
MongoDB에는 mongoose라는 ODM(Object-Document Mapping) 소프트웨어가 있었다면, SQL 또한 여러 종류의 ORM(Object-Relational Mapping) 소프트웨어가 있다. 그 중 이번 프로젝트에서 사용이 권장된 Prisma에 대해 알아보았다.
2) How does it work?:
# yarn 프로젝트를 초기화합니다. yarn init -y # express, prisma, @prisma/client 라이브러리를 설치합니다. yarn add express prisma @prisma/client # 설치한 prisma를 초기화 하여, prisma를 사용할 수 있는 구조를 생성합니다. npx prisma init
먼저 위의 명령어들을 사용해 prisma를 설치해준다. @prisma/client는 query builder 역할을 해준다. 마치 mongoose에서 Model.findOne()을 했던 것과 유사한 방식으로 JS 스크립트를 작성하여 DB 작업을 수행할 수 있다.
세 번째 명령어를 실행하면 프로젝트 디렉토리에 prisma 폴더가 생성되고, 해당 폴더 안에 schema.prisma라는 파일이 생성된다. 이 파일을 통해 Prisma가 DB를 설정해준다.
Prisma는 기본적으로 dotenv를 사용하기 때문에 init과 함께 .env 파일이 생성되는데, 여기서 DATABASE_URL 값을 aws의 RDS에서 확인할 수 있는 정보들로 알맞게 수정해줘야한다. 이번 프로젝트에는 dotenv에 추가로 dotenv-expand 패키지를 설치하여 ${}를 사용해 다른 값 들을 참조할 수 있도록 했다.
DATABASE_URL=${DB_PROVIDER}://${DB_USER}:${DB_PW}@${DB_HOST}:${DB_PORT}/${DB_NAME}
DB_PROVIDER: mysql이나 postgres 같은 엔진을 말한다.
DB_USER & DB_PW: DB 접속에 사용되는 유저 이름과 비밀번호를 말한다.
DB_HOST: aws RDS 콘솔에서 DB 인스턴스를 클릭하면 확인할 수 있는 endpoint 주소를 의미한다.
DB_PORT: 위에서 언급한 위치의 endpoint 바로 아래에 기재되어있다. MySQL의 기본 port는 3306이다.
DB_NAME: 인스턴스를 생성할 때 적어준 DB의 이름이다.
// schema.prisma generator client { provider = "prisma-client-js" } datasource db { provider = "postgresql" // change this to "mysql" url = env("DATABASE_URL") }
Prisma를 처음 init하면 생성되는 schema 파일의 내용물인데, client는 기본 primsa client를 사용하도록 두고, 아래 datasource db의 내용물 중 provider를 이번에 사용할 mysql로 변경해준다. 그 아래 url의 경우 .env에 정의된 DB URL 주소를 가지는 키의 이름을 적으면 된다. init에서 생성된 .env 파일에 자동으로 추가된 "DATABASE_URL"이 기본 값으로 설정되어있다.
3) Defining models:// schema.prisma model Products { productId Int @id @default(autoincrement()) @map("productId") productName String @unique @map("productName") price Int @default(1000) @map("price") info String? @map("info") @db.Text createdAt DateTime @default(now()) @map("createdAt") updatedAt DateTime @updatedAt @map("updatedAt") @@map("Products") }
schema.prisma 파일의 아래에 이런 식으로 model을 정의하여 추가해주면 DB에 해당 이름을 가지는 table이 생성된다.
- @id: 이 태그를 가진 field가 primary key가 된다.
- @default(): 아무런 값을 받지 못 한 경우 괄호 안의 값을 기본 값으로 가진다.
- autoincrement(): 자동으로 증가하는 값을 의미한다.
- @map(): 실제 DB에 어떤 이름으로 매핑되는지를 결정한다.
- String?: 타입 뒤에 ?를 붙여서 Nullable을 정의해 줄 수 있다.
- @@map(): 이 모델이 DB에서 어떤 이름의 table로 매핑될 지를 결정한다.
4) Push to DB:
# schema.prisma 파일에 설정된 모델을 바탕으로 MySQL에 정보를 업로드합니다. npx prisma db push # push할 스키마를 직접 선택 npx prisma db push --schema path/to/schema.prisma
schema.prisma 파일 작성을 완료하면 위 명령어를 사용하여 DB를 업데이트 해줄 수 있다.
5) Prisma Client:
이렇게 생성된 테이블을 수정하거나 조회하는 작업을 prisma client가 담당하는데, 사용하려면 PrismaClient 객체를 생성해야 한다.
// utils/prisma/index.js import PrismaClient from "@prisma/client"; export const prisma = new PrismaClient({ log: ["query", "info", "warn", "error"], errorFormat: "pretty", });
PrismaClient 객체를 router마다 선언해서 추가하여 사용할 수도 있겠지만, 그렇게 되면 앱은 하나인데 DB 연결이 라우터 개수 만큼 불어나는 불상사가 생긴다. 그래서 보통은 따로 파일을 만들어 PrismaClient 객체를 생성해주고, 이 객체를 export한 뒤 필요한 곳에 import 하여 사용하는 식으로 작성한다. 디자인 패턴의 Singleton과 같은 개념이라고 생각하면 된다.
6) Why use ORM?:
ORM을 사용하는 이유로는 복잡한 DB Query문 대신 Object와 key value 형태로 문서를 정의하여 코드를 깔끔하고 직관적이게 유지할 수 있고, 쿼리문 작성에 골머리 썩지 않고 로직 구현에 집중할 수 있어 생산성이 향상된다는 점이 있다.
클라이언트의 수가 많아지고 좀 더 복잡한 쿼리가 요구될 때 즈음에는 정교하게 설계된 query문이 ORM보다 더 빠르게 작동하는 경우가 있다고 한다. 프로젝트의 크기나 확장을 고려하여 적절한 방식을 선택하자.
--
REFERENCES:
> Node.js 숙련주차 강의 노트, 1주차
> aws, "RDS DB 인스턴스 생성"
> npmjs.com, prisma
>npmjs.com, @prisma/client
> npmjs.com, dotenv-expand
> prisma.io, Prisma documentation
728x90'TIL-sparta' 카테고리의 다른 글
[TIL] 스파르타) Node.js 숙련주차 강의 수강 - 3일 차 (JWT) (0) 2024.05.22 [TIL] 스파르타) Node.js 숙련주차 강의 수강 - 2일 차 (Cookie, Session) (0) 2024.05.21 [TIL] 프로그래머스) 76502 - 괄호 회전하기 (0) 2024.05.19 [TIL] 프로그래머스) 138476 - 귤 고르기 (Java) (0) 2024.05.18 [TIL] 스파르타) Ch.3 개인 과제 리뷰, Node 강의 수강 (0) 2024.05.17