본문 바로가기

BackEnd/nest.js

nest.js, @nest/config, @nest/mongoose 연동

@nest/mongoose 공식 문서 를 참고하여 작성했습니다. 

전체 소스코드는 github repository에서 확인 할 수 있습니다. 

 

프로젝트에 의존성 설치 

yarn add @nestjs/config @nestjs/dotenv @nestjs/mongoose mongoose

env 파일 생성

  • .development.env
DATABASE_HOST='your mongodb host'

- host에 id, password, host, db 이름 까지 포함 ex) 'mongodb://{id}:{pwd}@host/{dbname}

 

dynamic module 로드 

  • app.module.ts
import { Module } from '@nestjs/common';
import { ConfigModule, ConfigService } from '@nestjs/config';
import { MongooseModule } from '@nestjs/mongoose';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { CatsModule } from './cats/cats.module';

@Module({
  imports: [
    ConfigModule.forRoot({
      isGlobal: true,
      // 데모 프로젝트이므로 dev 환경의 .env를 고정으로 load,
      // 실제 프로덕트에는 환경에 따라 로드하는 파일의 path를 변경해주도록 해야함
      envFilePath: '.development.env',
    }),
    MongooseModule.forRootAsync({
      imports: [ConfigModule],
      useFactory: async (configService: ConfigService) => ({
        uri: configService.get('DATABASE_HOST'),
        authSource: 'admin',
      }),
      inject: [ConfigService],
    }),
    CatsModule,
  ],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}

tip : useFactory에서 option에 authSource 주는 이유

데모 프로젝트에서 mongodb 를 docker 컨테이너로 띄웠는데 root user 설정이 문제인지 Authentication failed가 발생했다. 

이 때 authSource 옵션을 'admin' 으로 지정하면 해결할 수 있다. 

 

참고 : mongoose docs의 authSource 옵션에 대한 설명 

  • authSource - The database to use when authenticating with user and pass. In MongoDB, users are scoped to a database. If you are getting an unexpected login failure, you may need to set this option.

 

스키마 작성

import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose';
import { Document } from 'mongoose';

export type CatDocument = Cat & Document;

@Schema()
export class Cat {
  @Prop()
  name: string;

  @Prop()
  age: number;

  @Prop()
  breed: string;
}

export const CatSchema = SchemaFactory.createForClass(Cat);

각 Schema는 MongoDB의 컬렉션에 mapping 되고 해당 컬렉션의 document의 모양을 정의하고 Model을 정의합니다.  

 

스키마 주입

- cats.module.ts

import { Module } from '@nestjs/common';
import { MongooseModule } from '@nestjs/mongoose';
import { Cat, CatSchema } from '../schemas/cats/cat.schema';
import { CatsController } from './cats.controller';
import { CatsService } from './cats.service';

@Module({
  imports: [
    MongooseModule.forFeature([
      {
        name: Cat.name,
        schema: CatSchema,
      },
    ]),
  ],
  controllers: [CatsController],
  providers: [CatsService],
})
export class CatsModule {}

해당 스키마를 사용할 모듈에 MongooseModule.forFeature로 작성한 Cat 스키마를 주입합니다. 스키마가 주입되면 @InjectModel 데코레이터를 사용해 모델을 주입받을 수 있습니다. 

 

cats.service.ts

import { Injectable } from '@nestjs/common';
import { InjectModel } from '@nestjs/mongoose';
import { Model } from 'mongoose';
import { Cat, CatDocument } from 'src/schemas/cats/cat.schema';
import { CreateCatDto } from './dto/create-cat.dto';

@Injectable()
export class CatsService {
  constructor(@InjectModel(Cat.name) private catModel: Model<CatDocument>) {}

  async create(createCatDto: CreateCatDto): Promise<Cat> {
    const createdCat = new this.catModel(createCatDto);
    return createdCat.save();
  }

  async findAll(): Promise<Cat[]> {
    return this.catModel.find().exec();
  }
}

여기까지 nest 가 제공하는 ConfigModule, MongooseModule 을 사용해 Mongodb 와 연동하는 예제를 살펴보았습니다.

 

 

'BackEnd > nest.js' 카테고리의 다른 글

nestjs + redis  (0) 2022.10.23