[NestJS] 데이터베이스 연동하기

2022. 12. 1. 22:55WEB.DEV/NestJS

반응형

안녕하세요.
이번 포스팅에서는 NestJS에서 데이터베이스를 연동하는 방법에 대해서 알아보겠습니다.

이 포스팅에서는 TypeORM을 이용해서 연동을 해보겠습니다.

제일 먼저 Nest 프로젝트를 생성을 하도록 하겠습니다.

$ nest new nest-database-example

프로젝트가 생성이 되었으면 데이터베이스 모듈을 생성을 해주도록 하겠습니다.

$ nest g mo database --flat

위의 명령어를 이용해서 database.module.ts를 생성을 하게 되면 src 폴더에 database.module.ts가 생성이 되고 src/app.module.ts의 imports에 등록이 되는것 까지 확인을 하실수 있습니다.

여기까지 했다면 이제는 TypeORM과 mysql 패지키를 설치하겠습니다.

$ yarn add @nestjs/typeorm typeorm mysql2

패키지가 설치가 되었다면 이제 database.module.ts에 아래와 같이 작성을 해줍니다.

import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';

@Module({
  imports: [
    TypeOrmModule.forRoot({
      type: 'mysql',
      host: 'localhost',
      port: 3306,
      username: 'root', // 데이터베이스 사용자
      password: 'root', // 데이터베이스 비밀번호
      database: 'nest_db_example', // 데이터베이스 스키마명
      entities: [__dirname + './**/*.entity{.ts,.js}'], // *.entity.ts 혹은 *.entity.js로 된 파일의 entity를 찾아서 등록
      synchronize: true
    }),
  ],
})
export class DatabaseModule {}

그리고 yarn start로 실행을 했을 때,
정상적으로 실행이 되었다면 아래와 같이 로그가 출력됩니다.

그리고 위에 입력한 database가 없는 경우 아래와 같이 로그가 출력됩니다.

그리고 위에 입력한 username 혹은 password가 잘못되었을 경우 아래와 같이 로그가 출력됩니다.

추가로 NestJS의 config를 이용해서 데이터베이스 모듈을 수정해보겠습니다.

먼저 .env 파일을 루트에 생성을 해줍니다.

DATABASE_HOST=localhost
DATABASE_PORT=3306
DATABASE_USER=root
DATABASE_PASSWORD=root
DATABASE_NAME=nest_db_example

그리고 NestJS의 config 패키지를 설치해주겠습니다.

$ yarn add @nestjs/config

그리고 app.module.ts에 추가를 해줍니다.

import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { DatabaseModule } from './database.module';
import { ConfigModule } from '@nestjs/config';

@Module({
  imports: [ConfigModule.forRoot(), DatabaseModule],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}

그리고 database.module.ts를 수정을 해주도록 하겠습니다.

import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';

@Module({
  imports: [
    TypeOrmModule.forRoot({
      type: 'mariadb',
      host: process.env.DATABASE_HOST,
      port: +(process.env.DATABASE_PORT || 3306),
      username: process.env.DATABASE_USER,
      password: process.env.DATABASE_PASSWORD,
      database: process.env.DATABASE_NAME,
      entities: [__dirname + './**/*.entity{.ts,.js}'],
      synchronize: true,
    }),
  ],
})
export class DatabaseModule {}

그리고 yarn start로 실행을 해보겠습니다.
그러면 config를 설정하기 전에 정상적으로 실행이 되었는데, 아래와 같이 로그가 출력이 되면서 오류가 발생합니다.

이유를 확인하기 위해서 아래와 같이 콘솔을 찍어보도록 하겠습니다.

import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';

console.log('1', process.env.DATABASE_HOST);

@Module({
  imports: [
    TypeOrmModule.forRoot({
      type: 'mariadb',
      host: process.env.DATABASE_HOST,
      port: +(process.env.DATABASE_PORT || 3306),
      username: process.env.DATABASE_USER,
      password: process.env.DATABASE_PASSWORD,
      database: process.env.DATABASE_NAME,
      entities: [__dirname + './**/*.entity{.ts,.js}'],
      synchronize: true,
    }),
  ],
})
export class DatabaseModule {
  constructor() {
    console.log('2', process.env.DATABASE_HOST);
  }
}

그리고 로그를 확인을 해보면 아래와 같이 출력이 됩니다.

@Module 전에는 process.env.DATABASE_HOST의 내용이 없다고 출력이 되고 module안에 consturtor에는 process.env.DATABASE_HOST가 정상적으로 출력이 됩니다.

예상을 해보면 Database Module이 실행이 될때는 Config Module이 설정이 완료되지 않고 그 이후에 완료가 된것으로 볼수 있을거 같습니다.

그렇다면 이걸 해결을 하려면 어떻게 하면 될까요? TypeOrmModule안에 메소드를 보면 forRoot가 있고 forRootAsync가 있습니다.
이 forRootAsync를 이용해서 해결을 할수 있습니다.
그런데 forRootAsync를 사용하면 기존에 추가한 type, host 등을 사용할수 없다고 합니다.

그럼 어떻게 해야 할까요?
방법은 config 파일을 생성을 해서 넣어주는 방법이 있습니다.

database.config.ts 파일을 생성을 해주도록 하겠습니다.

import { TypeOrmModuleOptions } from '@nestjs/typeorm';
import { registerAs } from '@nestjs/config';

export default registerAs(
  'database.config',
  (): TypeOrmModuleOptions => ({
    type: 'mysql',
    host: process.env.DATABASE_HOST,
    port: +(process.env.DATABASE_PORT || 3306),
    username: process.env.DATABASE_USER,
    password: process.env.DATABASE_PASSWORD,
    database: process.env.DATABASE_NAME,
    entities: [__dirname + './**/*.entity{.ts,.js}'],
    synchronize: true,
  }),
);

그리고 database.module.ts를 아래와 같이 변경을 해줍니다.

import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import databaseConfig from './database.config';

@Module({
  imports: [
    TypeOrmModule.forRootAsync({
      useFactory: databaseConfig,
    }),
  ],
})
export class DatabaseModule {}

그리고 다시 실행을 해보겠습니다.
그러면 아래와 같이 실행이 되는것을 볼수 있습니다.

여기까지 NestJS에서 TypeORM과 NestJS의 Config를 이용한 데이터베이스 연동하는 내용이었습니다.
위 내용의 Github Link 입니다.

 

GitHub - cheolubak/nest_database_example

Contribute to cheolubak/nest_database_example development by creating an account on GitHub.

github.com

많이 부족한 내용 봐주셔서 감사합니다.
다음 포스팅에는 Entity에 대해서 포스팅을 하도록 하겠습니다.
잘못된 내용 혹은 부족한 내용이 있다면 댓글로 알려주시면 수정 혹은 추가를 하도록 하겠습니다.

감사합니다💛

728x90
반응형