Nest는 SQl, NoSQL 모든 데이터베이스와 통합할 수 있다. 그런데 유독 nodejs는 NoSQL인 MongoDB를 사용하는 경우가 많다. MongoDB가 JSON과 유사한 BSON 객체로 데이터를 저장한다는 점, MongoDB의 ODM 중 가장 유명한 Mongoose가 nodejs 위에서 동작한다는 점 때문에 그런 것 같다. MongoDB는 계정 생성만 해 두고 사용해 본 적이 없어서 겸사겸사(?) NoSQL도 사용해 볼 겸 MongoDB를 연결해 보려고 한다.
ODM은 Object Document Mapping의 줄임말이다. 객체와 문서를 1대1 매칭한다는 뜻이다. Object는 자바스크립트의 객체, Document는 몽고디비의 문서이다. ODB은 문서를 DB에서 조회할 때 자바스크립트 객체로 바꿔 준다. 그리고 몽고디비의 ODM으로 가장 많이 사용되는 게 바로 몽구스다. 🐭
npm install --save @nestjs/mongoose mongoose
⁝
import { MongooseModule } from '@nestjs/mongoose';
@Module({
imports: [CatsModule, MongooseModule.forRoot('몽고디비URI')],
⁝
몽구스 설치가 완료되었으면 몽구스의 module을 app.module
에 import 해 주고 몽고디비 URI를 넣어 준다. URI를 얻는 방법은 아래와 같다.
cluster
들어가기connect
버튼 클릭Connect your application
버튼을 클릭그런데 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);
}
개발할 때 몽구스의 쿼리를 로그로 찍어 줄 수 있다. app.module
파일에 몽구스를 import * as mongoose from 'mongoose';
로 import한다. 그리고 AppModule 클래스에서 export 하는 코드 mongoose.set('debug', true)
를 작성한다. 이렇게 하면 쿼리가 로그로 찍힌다.
하지만 프로덕션 배포를 하게 될 때엔 해당 로그가 필요없다. 개발 모드와 프로덕션 모드를 구분해 주기 위해서 환경변수를 사용해 준다. .env
에 MODE = '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
로 가자.