Ayden's journal

Set up Prisma

초기 설치

우선 프로젝트에 개발 종속성으로 Prisma CLI를 설치하고, 이를 postgresql에 맞게 초기화해주어야 한다. 이 과정을 거치면 프로젝트 루트 경로에 prisma/schema.prisma 파일이 생성되게 된다. 이 파일에 schema를 작성한다.

// Prisma CLI 및 client 설치
npm install prisma --save-dev
npm install @prisma/client

// prisma가 postgresql을 받아 먹을 수 있게 초기화
npx prisma init --datasource-provider postgresql
// prisma/schema.prisma
datasource db {
  provider = "postgresql"
  url      = env("DATABASE_URL")
}

generator client {
  provider = "prisma-client-js"
}

model User {
  id    Int     @id @default(autoincrement())
  email String  @unique
  name  String?
}

이후 데이터베이스를 초기화하고 마이그레이션을 적용한 뒤 Prisma Client를 생성한다. 참고로 schema에 변경이 있을 때마다 새로운 Prisma Client를 생성해주어야 타입 안전성 유지에 도움이 된다.

// 데이터베이스를 초기화하고 마이그레이션을 적용
npx prisma migrate dev --name init

// Prisma Client를 생성
npx prisma generate

 

Prisma on ExpressJs

일반적으로 권장되는 방식은 PrismaClient를 통해 prisma 인스턴스를 만들고, 이 인스턴스를 통해 DB에 접근하는 것 같다.

const prisma = new PrismaClient()

const users = await prisma.user.findMany()

ExpressJs는 자유로운 어플리케이션 설계를 제공하지만, NestJs부터 접했던 나로서는 이 자유가 두려운 나머지 ExpressJs를 사용할 때도 모듈∙컨트롤러∙프로바이더를 칼같이 나누고 있다. 이들 각각은 클래스로 제공되기 때문에 PrismaClient를 직접 확장할 수 있다.

export class BoardRepository extends PrismaClient {
  async Board_update(patchBoardProps: PatchBoardProps, id: string) {
    const updateBoard = await this.board.update({
      where: {
        id,
      },
      data: { ...patchBoardProps },
    });

    return updateBoard;
  }
}

 

Prisma on NestJs

NestJs에서 모든 것은 일단 모듈이 된다. 공식문서에 따르면 prisma.service.ts를 만들고, 이를 prisma.module.ts로 제공하라고 되어있다. Jest 테스트는 굳이? 필요하지 않을 것 같아서 service 생성할때 --no-spec 옵션을 걸어두었다.

nest g mo prisma
nest g s prisma --no-spec
// prisma/prisma.service.ts
import { Injectable, OnModuleInit, OnModuleDestroy } from '@nestjs/common';
import { PrismaClient } from '@prisma/client';

@Injectable()
export class PrismaService extends PrismaClient implements OnModuleInit, OnModuleDestroy {
  async onModuleInit() {
    await this.$connect();
  }

  async onModuleDestroy() {
    await this.$disconnect();
  }
}
// prisma/prisma.module.ts
import { Global, Module } from '@nestjs/common';
import { PrismaService } from './prisma.service';

@Global()
@Module({
  providers: [PrismaService],
  exports: [PrismaService],
})
export class PrismaModule {}

 

@Global() 데코레이터를 사용해 Prisma 모듈을 전역 모듈로 선언했다. 이를 AppModule에 import하면 다른 모듈에서는 별도의 임포트 없이도 사용할 수 있다.

import { Module } from '@nestjs/common';
import { PrismaModule } from './prisma/prisma.module';

@Module({
  imports: [PrismaModule],
})
export class AppModule {}

블로그의 정보

Ayden's journal

Beard Weard Ayden

활동하기