본문 바로가기

STUDY/Node.js

NestJS | 데이터베이스 연결, 설정 정보를 입력하는 다양한 방법... (database connection)

필요한 종속성 설치

Nest는 TypeORM을 사용한다. @nestjs/typeorm이라는 자체 패키지를 제공하고 있다.

npm install --save @nestjs/typeorm typeorm mysql2

TypeORM

DB 연결!

1. app.module.ts에서 바로 설정값 넣어버리기

TypeOrmModule.forRoot()메서드로 커넥션에 필요한 정보를 입력한다.

// 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파일로 설정하기

프로젝트의 루트 디렉터리에 ormconfig.json파일을 생성한 뒤, 아래처럼 필요한 설정값들을 json형식으로 입력하면 forRoot()메서드가 자동으로 인식한다.

entities는 엔티티 파일들이 위치하는 경로를 설정한다.

// 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()]
})

3. ormconfig.js파일로 설정하기

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

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,
};

app.module.ts는 동일. forRoot()만 호출하면 된다

4. configService를 이용하는 방법

NestJS 공식문서 - Async Configuration

.env파일에 작성된 값을 불러와 설정하는 방법인데, ConfigService를 이용한다.
ConfigService를 이용하기 위해서는 @nestjs/config패키지가 필요하다.

$ npm i --save @nestjs/config

/src/config/database경로에 맞게 폴더를 생성한 후, 먼저 서비스부터 작성

// /src/config/database/config.service.ts

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

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

  createTypeOrmOptions(): TypeOrmModuleOptions {
    return {
      type: 'mysql',
      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 { MySqlConfigService } from './config.service';

@Module({
  providers: [MySqlConfigService],
})
export class MySqlConfigModule {}

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 { ConfigModule } from '@nestjs/config';
import { TypeOrmModule } from '@nestjs/typeorm';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { MySqlConfigModule } from './config/database/config.module';
import { MySqlConfigService } from './config/database/config.service';
import { UserModule } from './user/user.module';

@Module({
  imports: [
    ConfigModule.forRoot({ isGlobal: true }),
    TypeOrmModule.forRootAsync({
      imports: [MySqlConfigModule],
      useClass: MySqlConfigService,
      inject: [MySqlConfigService],
    }),
  ],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}

간단하게 API작성해보기

잘 되나 한 번 확인해보자..

엔티티

// /src/user/entity/user.entity.ts

import { Column, Entity, PrimaryGeneratedColumn } from 'typeorm';

@Entity()
export class User {
  @PrimaryGeneratedColumn()
  id: number;

  @Column()
  name: string;

  @Column()
  address: string;
}

repository

// /src/user/entity/user.repository.ts

import { EntityRepository, Repository } from 'typeorm';
import { User } from './user.entity';

@EntityRepository(User)
export class UserRepository extends Repository<User> {}

service

// /src/user/user.service.ts

import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { User } from 'src/user/entity/user.entity';
import { UserRepository } from 'src/user/entity/user.repository';

@Injectable()
export class UserService {
  constructor(
    @InjectRepository(User)
    private userRepository: UserRepository,
  ) {}

  findAll(): Promise<User[]> {
    return this.userRepository.find();
  }
}

controller

// /src/user/user.conroller.ts

import { Controller, Get } from '@nestjs/common';
import { UserResponseDto } from './dto/response.dto';
import { UserService } from './service/user.service';

@Controller('users')
export class UserController {
  constructor(private readonly userService: UserService) {}

  @Get()
  async getUsers(): Promise<UserResponseDto[]> {
    return await this.userService.findAll();
  }
}

module

// /src/user/user.module.ts

import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { User } from './entity/user.entity';
import { UserService } from './service/user.service';
import { UserController } from './user.controller';

@Module({
  imports: [TypeOrmModule.forFeature([User])],
  controllers: [UserController],
  providers: [UserService],
})
export class UserModule {}

AppModule에서 UserModule 추가

// ..생략

@Module({
  imports: [
    ConfigModule.forRoot({ isGlobal: true }),
    TypeOrmModule.forRootAsync({
      imports: [MySqlConfigModule],
      useClass: MySqlConfigService,
      inject: [MySqlConfigService],
    }),
    UserModule,
  ],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}

된다요~

 


 

 

Documentation | NestJS - A progressive Node.js framework

Nest is a framework for building efficient, scalable Node.js server-side applications. It uses progressive JavaScript, is built with TypeScript and combines elements of OOP (Object Oriented Progamming), FP (Functional Programming), and FRP (Functional Reac

docs.nestjs.com