NestJS와 MongoDB 연결하기 (feat. 환경변수와 Mongoose)

bin-lee·2022년 1월 6일
1

Nest는 SQl, NoSQL 모든 데이터베이스와 통합할 수 있다. 그런데 유독 nodejs는 NoSQL인 MongoDB를 사용하는 경우가 많다. MongoDB가 JSON과 유사한 BSON 객체로 데이터를 저장한다는 점, MongoDB의 ODM 중 가장 유명한 Mongoose가 nodejs 위에서 동작한다는 점 때문에 그런 것 같다. MongoDB는 계정 생성만 해 두고 사용해 본 적이 없어서 겸사겸사(?) NoSQL도 사용해 볼 겸 MongoDB를 연결해 보려고 한다.

ODM?

ODM은 Object Document Mapping의 줄임말이다. 객체와 문서를 1대1 매칭한다는 뜻이다. Object는 자바스크립트의 객체, Document는 몽고디비의 문서이다. ODB은 문서를 DB에서 조회할 때 자바스크립트 객체로 바꿔 준다. 그리고 몽고디비의 ODM으로 가장 많이 사용되는 게 바로 몽구스다. 🐭


🧀 몽구스 설치와 몽고DB 연결

npm install --save @nestjs/mongoose mongoose
⁝
import { MongooseModule } from '@nestjs/mongoose';

@Module({
  imports: [CatsModule, MongooseModule.forRoot('몽고디비URI')],
⁝

몽구스 설치가 완료되었으면 몽구스의 module을 app.module에 import 해 주고 몽고디비 URI를 넣어 준다. URI를 얻는 방법은 아래와 같다.

  1. 몽고디비 cluster 들어가기
  2. connect 버튼 클릭
  3. Connect your application 버튼을 클릭
  4. 이미지의 uri를 복사한다

🧀 환경 변수 설정하기

그런데 URI를 복사하여 MongooseModule.forRoot('몽고디비URI')에 붙여넣으면 URI가 날것의 주소 그대로 노출되고 만다. URI는 반드시 노출을 막아야 하기 때문에 환경 변수를 설정해 줄 필요가 있다.

환경 변수 설정을 위해서는 별도의 설치와 import가 필요하다. (공식 홈페이지 TECHNIQUES의 Configuration 참고)

$ npm i --save @nestjs/config
⁝
import { ConfigModule } from '@nestjs/config';

@Module({
  imports: [ ConfigModule.forRoot(), MongooseModule.forRoot('몽고디비URI')]
⁝

설치와 import를 마치면 환경변수 관리 파일 .env를 사용할 수 있다. .env 파일은 프로젝트 폴더 가장 상위 루트에서 생성해 주면 된다. 이렇게 생성된 파일에 아까 복사했던 몽고디비 URI 값을 MONGODB_URI = "복사했던 몽고디비 URI 값" 형태로 저장한다.

날것의 URI가 들어 있던 app.module 파일의 MongooseModule.forRoot('몽고디비URI')'몽고디비URI' 부분을 process.env.MONGODB_URI로 수정해 준다. 첫 번째 인자 설정을 마쳤으면 이제 두 번째 인자를 넣어 줄 차례다.

완성된 코드로 보면 아래와 같다.

⁝
@Module({
  imports: [
    ConfigModule.forRoot(),
    MongooseModule.forRoot(process.env.MONGODB_URI, {
      useNewUrlParser: true,	// 몽구스에서 필요로 하는 두 번째 인자 -1
      useUnifiedTopology: true,	// 몽구스에서 필요로 하는 두 번째 인자 -2	
    }),
    CatsModule,
  ],
  controllers: [AppController],
  providers: [AppService],
})
  ⁝

몽고디비 URI 외에도 포트 넘버 등을 환경 변수에 넣어 관리할 수 있다. main에서 사용하고 있는 포트 넘버를 .env에 넣고 설정을 해 보았다.

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  app.useGlobalFilters(new HttpExceptionFilter());
  const PORT = process.env.PORT; // .env에 저장된 포트 넘버
  await app.listen(PORT);
}

🧀 console에 몽구스 쿼리 출력 설정

개발할 때 몽구스의 쿼리를 로그로 찍어 줄 수 있다. app.module 파일에 몽구스를 import * as mongoose from 'mongoose';로 import한다. 그리고 AppModule 클래스에서 export 하는 코드 mongoose.set('debug', true)를 작성한다. 이렇게 하면 쿼리가 로그로 찍힌다.

하지만 프로덕션 배포를 하게 될 때엔 해당 로그가 필요없다. 개발 모드와 프로덕션 모드를 구분해 주기 위해서 환경변수를 사용해 준다. .envMODE = 'dev'로 구분해 주는 코드를 작성했다.

app.module로 다시 이동해서 processe.env.MODE가 'dev'일 때만 로그가 찍히도록 삼항 조건 연사자를 이용한다. 완성된 클래스 코드와 찍힌 쿼리는 아래와 같다.

export class AppModule implements NestModule {
  private readonly idDev: boolean = process.env.MODE === 'dev' ? true : false;
  configure(consumer: MiddlewareConsumer) {
    consumer.apply(LoggerMiddleware).forRoutes('*');
    mongoose.set('debug', this.idDev);
  }
}
// 찍힌 쿼리 적기

개발할 때는 true가, 아닐 때에는 false 되어서 쿼리가 찍히지 않게 된다.


느낀점
포스팅을 정리하면서 환경 변수를 왜 사용하는지에 대한 이해를 할 수 있었다. 노출되면 안 될 중요한 정보들은 환경 변수에 담자.

몽고디비를 연결할 때, 몽구스의 쿼리를 보고자 설정할 때 모두 app.module과 관련이 있다. .env에서 환경변수를 설정하고 app.module로 가자.

profile
🚀 오늘 배운 건 오늘 적자

0개의 댓글