본문 바로가기
카테고리 없음

Nestjs DB 연결

by 아구몬선생 2022. 8. 5.

1. app.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: 'test',
        entities: [],
        synchronize: true,
    }),
  ],
})
export class AppModule {}

2. ormconfig.json 파일로 설정(위치는 프로젝트 루트)

{
  "type": "mysql",
  "host": "localhost",
  "port": 3306,
  "username": "root",
  "password": "root",
  "database": "test",
  "entities": ["dist/**/*.entity{.ts,.js}"],
  "synchronize": true
}

forRoot()를 호출할수 있다

// app.module.ts

@Module({
    imports: [TypeOrmModule.forRoot()]
})

장점

DB 비밀번호라던지 민감한 정보들이 있으므로 파일을 따로 만들어 보관하는 편이 보안 측면에 좋다. 나중에 gitignore에 추가해서 이 파일만 빼고 깃허브에 올릴 수도 있다.

단점1

forRoot() 메소드를 통해 사용할 수 있었던 추가적인 설정들을 바로 사용할 수 없다.
추가적인 설정 속성에는 autoLoadEntities, retryDelay 등이 있다.

 

하지만 적용방법이 있다

getConnectionOptions을  사용하면 된다.

// app.module.ts
TypeOrmModule.forRootAsync({
  useFactory: async () =>
    Object.assign(await getConnectionOptions(), {
      autoLoadEntities: true,
    }),
})

단점 2

ormconfig.json 파일을 사용한다면 내가 사용할 entity를 경로로 설정할 수밖에 없다. 

"entities": ["dist/**/*.entity{.ts,.js}"]

 이렇게 말이다. 이렇게 되면 모든 entity가 실제 DB상의 테이블로 만들어진다. 하지만, entity 중에서 실제 테이블로 만들면 안 되는 것들이 있다. 예를 들어 그저 다른 테이블에서 참고하기 위해 만들어진 entity 말이다.

 

하지만 이것도 파일을 제외하는 걸로 보안할 수 있다

{
    entities: ['src/entity/**/!(*.test.ts)']
}

.env파일에서 환경변수로 작성한 다음 그값을 이용

// .env

DB_USER=root
DB_PASSWORD=root
DB_PORT=3306
DB_HOST=localhost
DB_SCHEMA=test
ENTITY_PATH=dist/**/**/*.entity{.js,.ts}
// ormconfig.js

module.exports = {
  type: 'mysql',
  entities: [process.env.ENTITY_PATH],
  username: process.env.DB_USER,
  password: process.env.DB_PASSWORD,
  host: process.env.DB_HOST,
  database: process.env.DB_SCHEMA,
  synchronize: true,
};

3. configService 를 이용하는 방법(공식문서)

.env파일에 작성된 값을 불러와 설정하는 방법인데, ConfigService를 이용한다.

ConfigService를 이용하기 위해서는 @nestjs/config패키지가 필요하다.

$ npm i --save @nestjs/config

경로에 맞게 폴더 생성 후

import { Injectable } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { TypeOrmModuleOptions, TypeOrmOptionsFactory } from '@nestjs/typeorm';

@Injectable()
export class PgConfigService implements TypeOrmOptionsFactory {
  constructor(private configService: ConfigService) {}

  createTypeOrmOptions(): TypeOrmModuleOptions {
    return {
      type: 'postgres',
      username: this.configService.get<string>('DB_USER'),
      password: this.configService.get<string>('DB_PASSWORD'),
      port: +this.configService.get<number>('DB_PORT'),
      host: this.configService.get<string>('DB_HOST'),
      database: this.configService.get<string>('DB_SCHEMA'),
      entities: ['dist/**/**/*.entity{.ts,.js}'],
      // autoLoadEntities: true,
    };
  }
}

그리고 모듈에 서비스를 불러온다

// /src/config/database/config.module.ts

import { Module } from '@nestjs/common';
import { PgConfigService } from './config.service';

@Module({
  providers: [PgConfigService],
})
export class PgConfigModule {}

autoLoadEntities는 엔티티들을 자동으로 불러오는 설정이다.

이제 **app.module.ts**에서 설정을 아래와 같이 변경한다.

  • **ConfigModule.forRoot({ isGlobal: true})**는 전역 모듈로 설정하겠다는 설정이다.
    • app.module.ts에서 **ConfigModule.forRoot()**를 imports하지 않으면 configService를 사용할 수 없다.
  • **TypeOrmModule.forRootAsync()**는 데이터베이스에 연결하기 위한 옵션들을 비동기적으로 설정한다.
    • imports와 inject로 필요한 의존성을 주입한다.
    import { Module } from '@nestjs/common';
    import { AppController } from './app.controller';
    import { AppService } from './app.service';
    import { TypeOrmModule } from '@nestjs/typeorm';
    import { PgConfigModule } from './config/database/config.module';
    import { PgConfigService } from './config/database/config.service';
    import { ConfigModule } from '@nestjs/config';
    
    @Module({
      imports: [
        //app.module.ts에서 **ConfigModule.forRoot()**를 imports하지 않으면 configService
        ConfigModule.forRoot({ isGlobal: true }), //isGlobal 전역 모듈로 설정하겠다는 설정 
        TypeOrmModule.forRootAsync({ //데이터베이스에 연결하기 위한 옵션들을 비동기적으로 설정한다
          imports: [PgConfigModule], //의존성 주입
          useClass: PgConfigService,
          inject: [PgConfigService], //의존성 주입
        }),
      ],
      controllers: [AppController],
      providers: [AppService],
    })
    export class AppModule {}