Skip to content

Commit

Permalink
feat(be): add 7.Prisma
Browse files Browse the repository at this point in the history
  • Loading branch information
cho-to committed Nov 14, 2023
1 parent 452f44f commit 824a1f7
Showing 1 changed file with 259 additions and 1 deletion.
260 changes: 259 additions & 1 deletion content/docs/backend/7. Prisma.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 를 눈으로 확인할 수 있으니 애용해주세요 😻

0 comments on commit 824a1f7

Please sign in to comment.