
개인 토이프로젝트로 개발을 진행중 백엔드 엔진으로 NestJs를 사용하기로 했다.
이유는 Spring만 하다가 다른걸 해보고 싶다는 단순한 생각으로.
ORM은 Prisma를 선택하여 연동 방법을 기록으로 남긴다.
참고자료
nest new prisma-project ↲
cd prisma-project ↲
npm i -D prisma ↲
npx prisma ↲ → 설치확인
npx prisma init ↲
supabase에서 프로젝트를 생성한다.
supabase -> settings -> Database로 이동을 하면 Connection string을 확인 할수 있다.

Mode를 Session으로 변경해야 한다.
URI항목을 복사한다.
.env파일에 붙어 녛기 한다.
/prisma/schema.prisma 수정
model Todo {
id String @id @default(uuid())
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
title String @db.VarChar(255)
content String
done Boolean
}
npx prisma migrate dev --name init ↲
추가정보
모듈별로 schema를 분리 하고자 할때
/src/prisma
└/schema
├/todos
│ └todos.prisma
└schema.prisma generator client {
provider = "prisma-client-js"
previewFeatures = ["prismaSchemaFolder"]
}model todos{
id String @id @default(uuid())
createdAt DateTime @default(now())
updatedAt DateTime? @updatedAt
title String @db.VarChar(255)
content String?
done Boolean @default(false)
}npx prisma migrate dev --name partition ↲
npm i @prisma/client ↲
npm i @nestjs/config ↲
prisma.module, prisma.service를 생성한다.
nest g mo prisma ↲
nest g s prisma ↲
prisma.moule 수정
import { Module, Global } from '@nestjs/common';
import { PrismaService } from './prisma.service';
+ @Global()
@Module({
providers: [PrismaService],
+ exports: [PrismaService],
})
export class PrismaModule {}
prisma.service 수정
import { Injectable, OnModuleDestroy, OnModuleInit } from '@nestjs/common';
import { PrismaClient } from '@prisma/client';
@Injectable()
export class PrismaService
extends PrismaClient
implements OnModuleInit, OnModuleDestroy
{
constructor() {
super({
datasources: {
db: {
url: process.env.DATABASE_URL,
},
},
});
}
async onModuleInit() {
await this.$connect();
}
async onModuleDestroy() {
await this.$disconnect();
}
async enableShutdownHooks(app: INestApplication) {
process.on('beforeExit', async () => {
await app.close();
});
}
}
main.ts 수정
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
await app.listen(process.env.PORT ?? 3000);
+ const prismaService = app.get(PrismaService);
+ await prismaService.enableShutdownHooks(app);
}
bootstrap();
app.module수정
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { TodosModule } from './todos/todos.module';
+ import { PrismaModule } from './prisma/prisma.module';
@Module({
+ imports: [PrismaModule, TodosModule],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}
crud를 위하여 기본 리소스를 생성한다.
nest g res todos ↲
? What transport layer do you use? REST API ↲
? Would you like to generate CRUD entry points? Yes ↲
src/todos/의 위치에 파일들이 생성된걸 볼수 있다.
/src/todos
├/dto
│ ├create-todo.dto.ts
│ └update-todo.dto.ts
├/entities
│ └todo.entity.ts
├todos.controller.ts
├todos.module.ts
└todos.service.ts
export class CreateTodoDto {
title: string;
content: string;
}
import { Injectable } from '@nestjs/common';
import { CreateTodoDto } from './dto/create-todo.dto';
import { UpdateTodoDto } from './dto/update-todo.dto';
import { PrismaService } from 'src/prisma/prisma.service';
import { Prisma } from '@prisma/client';
@Injectable()
export class TodosService {
constructor(private prisma: PrismaService) {}
private readonly model = this.prisma.todos;
create(data: Prisma.todosCreateInput) {
return this.model.create({ data });
}
findAll() {
return this.model.findMany();
}
findOne(todosWhereUniqueInput: Prisma.todosWhereUniqueInput) {
return this.model.findUnique({ where: todosWhereUniqueInput });
}
update(params: {
where: Prisma.todosWhereUniqueInput;
data: Prisma.todosUpdateInput;
}) {
return this.model.update(params);
}
remove(todosWhereUniqueInput: Prisma.todosWhereUniqueInput) {
return this.model.delete({ where: todosWhereUniqueInput });
}
}
import {
Controller,
Get,
Post,
Body,
Patch,
Param,
Delete,
} from '@nestjs/common';
import { TodosService } from './todos.service';
import { CreateTodoDto } from './dto/create-todo.dto';
import { UpdateTodoDto } from './dto/update-todo.dto';
@Controller('todos')
export class TodosController {
constructor(private readonly todosService: TodosService) {}
@Post()
create(@Body() createTodoDto: CreateTodoDto) {
return this.todosService.create(createTodoDto);
}
@Get()
findAll() {
return this.todosService.findAll();
}
@Get(':id')
findOne(@Param('id') id: string) {
return this.todosService.findOne({ id: id });
}
@Patch(':id')
update(@Param('id') id: string, @Body() updateTodoDto: UpdateTodoDto) {
return this.todosService.update({ where: { id: id }, data: updateTodoDto });
}
@Delete(':id')
remove(@Param('id') id: string) {
return this.todosService.remove({ id: id });
}
}