From 824a1f72e8ebc081de24c2caa7d94ae730dd000f Mon Sep 17 00:00:00 2001 From: cho-to Date: Tue, 14 Nov 2023 10:05:00 +0900 Subject: [PATCH] feat(be): add 7.Prisma --- content/docs/backend/7. Prisma.md | 260 +++++++++++++++++++++++++++++- 1 file changed, 259 insertions(+), 1 deletion(-) diff --git a/content/docs/backend/7. Prisma.md b/content/docs/backend/7. Prisma.md index bbea8d3..8913549 100644 --- a/content/docs/backend/7. Prisma.md +++ b/content/docs/backend/7. Prisma.md @@ -7,4 +7,262 @@ lastmod = "2023-09-08" weight = 170 +++ -{{< alert context="info" text="작성 준비 중입니다! 조금만 기다려주세요. 🥹" />}} +이번 시간에는 Node.js & TypeScript의 ORM 중 하나인 Prisma에 대해 알아봅시다. + +## 공부할 내용 📚 + +### 1. Prisma가 무엇인가요? + +ORM...?? ORM은 뭐고, Prisma는 또 무엇일까요? + +ORM의 의미와, Prisma가 어떤 서비스인지 한 번 알아봅시다! + +- [ORM이 뭘까?](https://velog.io/@gndan4/ORM이란): ORM이 뭔지 간단히 알아봅시다! + - 이외에도 구글링하면 ORM에 대해서 많은 정보들이 나오니 참고해주세요! 😀 +- [Is Prisma an ORM?](https://www.prisma.io/docs/concepts/overview/prisma-in-your-stack/is-prisma-an-orm): Prisma 공식문서에서 Prisma가 무엇인지, 어떤 원리로 작동되는지에 대해서 간단히 소개해줍니다. + - [Prisma란?](https://velog.io/@hwisaac/Prisma-%EB%9E%80): 한글로도 짧게 정리한 블로그 글도 가져와봤습니다! + +### 2. Prisma + +이제 ORM이 무엇이고, Prisma는 어떤 서비스인지 알아보았으니 구체적으로 어떻게 사용할 수 있는지 알아볼까요? + +- [What is Prisma?](https://www.prisma.io/docs/concepts/overview/what-is-prisma): Prisma의 작동 원리에 대해서 알아봅니다. 꼭 읽어봐주세요!! ⭐️ +- [Prisma schema](https://www.prisma.io/docs/concepts/components/prisma-schema): Prisma는 schema 파일을 통해 다양한 설정 정보를 얻고 어떠한 데이터 모델을 생성할지 파악합니다. schema 파일이 어떻게 구성되어 있고, 데이터 모델은 어떻게 작성할 수 있는지 살펴봐야겠죠? 😆 +- [Prisma CRUD](https://www.prisma.io/docs/concepts/components/prisma-client/crud): Prisma에서는 아주 많은.... 기능들이 있는데요, 이번에는 그중 실습때 쓰이는 CRUD관련 기능만 살펴봐주세요 🙂 +- [Prisma Playground](https://playground.prisma.io): Prisma에서는 Playground를 통해 웹에서도 테스트할 수 있도록 해줘요! Playground를 통해 한 번 테스트해봐도 좋아요! + - [Prisma Client API reference](https://www.prisma.io/docs/reference/api-reference/prisma-client-reference): API reference인데, 궁금하신 부분있으면 찾아봐도 괜찮을 것 같아요! + +## 프로젝트 실습 🎈 + +이번 주차는 저번 주차에서 만들었던 Nest.js 웹서버에서 실제 데이터베이스(PostgreSQL)에 prisma를 이용하여 CRUD 코드를 작성해보는 과제입니다. + +> 환경 설정 관련해서 아래 지시사항을 따라해주세요! +> 물론 꼭 그대로 따라하실 필요는 없고 자신의 데이터 구조에 따라 바꾸셔도 괜찮습니다! + +### 실습 세부 설명 ⚙️ + +환경세팅과 관련해서 도와드릴게요! +밑의 절차를 따라와주세요 + +> 참고 : https://www.prisma.io/blog/nestjs-prisma-rest-api-7D056s1BmOL0 + +Root 디렉토리에 `docker-compose.yml`를 생성하고, 아래 파일을 복사-붙여넣기 해주세요. +```docker +# docker-compose.yml + +version: '3.8' +services: + postgres: + image: postgres:13.5 + restart: always + environment: + - POSTGRES_USER=myuser + - POSTGRES_PASSWORD=mypassword + volumes: + - postgres:/var/lib/postgresql/data + ports: + - '5432:5432' + +volumes: + postgres: +``` +그 뒤, 터미널에서 `docker-compose up -d` 을 실행하고(`-d`는 백그라운드에서 실행하는 옵션) , 정상적으로 컨테이너가 생성되고 실행되는지 확인해주세요 + +- 터미널에 Running 표시 혹은 docker gui 에서 실행되고 있다면 성공입니다 +- **🛠️ 백그라운드에서 정상적으로 작동해야지 밑의 과정에서 오류가 생기지 않습니다!** + + +다음으로 터미널에 `npm install -D prisma` 을 입력해 prisma 를 설치해줍니다. + +루트 디렉토리에서 `npx prisma init` 를 입력하면, prisma 폴더와 Schema 파일이 생성된 것을 확인할 수 있습니다. + +- 루트 폴더에 ***.env*** 파일이 생성되었는 것을 볼 수 있는데요, 안에는 database_url 이 들어있을 건데 밑과 같이 변경해줍니다. + + ```docker + // .env + DATABASE_URL="postgres://myuser:mypassword@localhost:5432/median-db" + ``` + +`prisma/schema.prisma` 에 들어가 맨 밑에 restaurant model 을 추가해줍시다! +- 자신의 데이터구조에 맞게 자유롭게 작성해주시면 됩니다! 제가 작성한 예시를 남겨드립니다. + + ```docker + // This is your Prisma schema file, + // learn more about it in the docs: https://pris.ly/d/prisma-schema + + generator client { + provider = "prisma-client-js" + } + + datasource db { + provider = "postgresql" + url = env("DATABASE_URL") + } + + model Restaurant { + id Int @id @default(autoincrement()) + name String @unique + address String + phone String + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + } + ``` + +다음, 우리가 생성한 데이터 모델을 migrate하기 위해 아래 명령어를 입력해줍니다. +```shell +npx prisma migrate dev --name "init" +``` +- 성공적으로 되었다면 terminal에 `Your database is now in sync with your schema`라는 문장과 함께 `prisma` 안에 `migration` 폴더가 생성되는 것을 확인할 수 있어용 + +원활한 테스팅을 위해 데이터베이스에 미리 seed 데이터도 심어놓읍시다. +- 아래 `seed.ts`를 생성해주세요! (데이터 구조는 자신의 것과 일치하게 수정해주셔도 됩니당) +```jsx +// prisma/seed.ts + +import { PrismaClient } from '@prisma/client'; + +// initialize Prisma Client +const prisma = new PrismaClient(); + +async function main() { + // create two dummy articles + const restaurant1 = await prisma.restaurant.upsert({ + where: { name: '봉수육' }, + update: {}, + create: { + name: '봉수육', + address: '경기 수원시 장안구 율전로108번길 11 1층', + phone: '0507-1460-0903', + }, + }); + + const restaurant2 = await prisma.restaurant.upsert({ + where: { name: '청년밥상' }, + update: {}, + create: { + name: '청년밥상', + address: '경기 수원시 장안구 서부로2136번길 10 1층', + phone: '0507-1307-1822', + }, + }); + + console.log({ restaurant1, restaurant2 }); +} + +// execute the main function +main() + .catch((e) => { + console.error(e); + process.exit(1); + }) + .finally(async () => { + // close Prisma Client at the end + await prisma.$disconnect(); + }); +``` + +그리고 `package.json`에 아래 명령어를 추가해주세요. +```jsx +// package.json + +// ... + "scripts": { + // ... + }, + "dependencies": { + // ... + }, + "devDependencies": { + // ... + }, + "jest": { + // ... + }, + **"prisma": { + "seed": "ts-node prisma/seed.ts" + }** +``` +그리고 터미널에 `npx prisma db seed`를 입력해주시면 귀여운 새싹모양 아이콘이 뜰거에요ㅎ.ㅎ + +prisma를 연결해주기 위해 + +```shell +npx nest generate module prisma +npx nest generate service prisma +``` + +를 입력해주시고, `prisma.service.ts` 파일을 조금 수정해줍니다. + +```jsx +// src/prisma/prisma.service.ts + +import { INestApplication, Injectable } from '@nestjs/common'; +import { PrismaClient } from '@prisma/client'; + +@Injectable() +export class PrismaService extends PrismaClient { + async enableShutdownHooks(app: INestApplication) { + this.$on('beforeExit', async () => { + await app.close(); + }); + } +} +``` + +그리고 `prisma.module.ts` 도 수정해줍니다. (exports에 추가) + +```jsx +// src/prisma/prisma.module.ts + +import { Module } from '@nestjs/common'; +import { PrismaService } from './prisma.service'; + +@Module({ + providers: [PrismaService], + exports: [PrismaService], +}) +export class PrismaModule {} +``` + +마지막으로 저희 Restaurant 모듈에서 쓰기 위하여 service, module 파일을 조금 수정해주세요! +- 밑에는 예시 코드입니다. +```jsx +//restaurant.module.ts +import { Module } from '@nestjs/common'; +import { PrismaModule } from 'src/prisma/prisma.module'; +import { RestaurantController } from './restaurant.controller'; +import { RestaurantService } from './restaurant.service'; + +@Module({ + controllers: [RestaurantController], + providers: [RestaurantService], + imports: [PrismaModule], +}) +export class RestaurantModule {} +``` + +```jsx +//restaurant.service.ts +import { Injectable } from '@nestjs/common'; +import { PrismaService } from 'src/prisma/prisma.service'; + +@Injectable() +export class RestaurantService { + constructor(private prisma: PrismaService) {} + + //example + async getAllRestaurants() { + return await this.prisma.restaurant.findMany({ + select: { + name: true, + address: true, + phone: true, + }, + }); + } +} +``` + +이제 직접 CRUD 코드를 작성하면 됩니다. 😆 +- 참고로, `npx prisma studio` 를 입력하면 5555포트에서 정말 간편하게 db 를 눈으로 확인할 수 있으니 애용해주세요 😻 \ No newline at end of file