[Nest.js] MongoDB 연동

Woong·2022년 11월 21일
0

Nestjs

목록 보기
3/28

Mongoose 설치

npm i @nestjs/mongoose mongoose

Mongoose Module 설정

import { Module } from '@nestjs/common';
import { MongooseModule } from '@nestjs/mongoose';

@Module({
  imports: [MongooseModule.forRoot(process.env.MONGODB_URL)],
})
export class AppModule {}
  • process.env 는 프로젝트 최상단에 .env 파일에 정의한 환경변수 값을 로딩
    • ex) MONGODB_URL=mongodb://my_user:my_pw@127.0.0.1:27017/my_db
    • ex) MONGODB_URL=mongodb://my_user:my_pw@remote_host1:27017,remote_host2:27017/my_db

Schema 정의

  • @Schema 데코레이터를 통해 Schema 지정
    • collection 을 지정하지 않을시, 클래스명에 s 붙인 값이 기본으로 지정
  • @Prop 데코레이터로 MongoDB 에 매핑할 필드 지정
    • @Prop 데코레이터가 없을 경우 MongoDB 에 매핑되지 않음
    • 필수 여부, 기본값, 불변 여부 등 설정 가능
    • ex) @Prop({ required: true })
import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose';
import { HydratedDocument } from 'mongoose';

export type CatDocument = HydratedDocument<Cat>;

@Schema({ collection: 'cats' })
export class Cat {
  @Prop({ required: true })
  name: string;

  @Prop()
  age: number;

  @Prop()
  breed: string;
}

export const CatSchema = SchemaFactory.createForClass(Cat);
  • 다른 collection 에 참조가 있을 경우 @Prop 으로
import * as mongoose from 'mongoose';
import { Owner } from '../owners/schemas/owner.schema';

// inside the class definition
@Prop({ type: mongoose.Schema.Types.ObjectId, ref: 'Owner' })
owner: Owner;

Module 설정

  • 위에서 정의한 Schema 와 그외 Controller, Service 등 관리
    • forFeature 에서 지정된 name 이 injection token 명이 됨
import { Module } from '@nestjs/common';
import { MongooseModule } from '@nestjs/mongoose';
import { CatsController } from './cats.controller';
import { CatsService } from './cats.service';
import { Cat, CatSchema } from './schemas/cat.schema';

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

Service 에서 Model injection

  • @InjectModel 데코레이터를 이용해 Service 에 Model 을 injection
import { Model } from 'mongoose';
import { Injectable } from '@nestjs/common';
import { InjectModel } from '@nestjs/mongoose';
import { Cat, CatDocument } from './schemas/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();
  }
}

테스트시 주입

  • getModelToken 인자로 @InjectModel 첫번째 인자와 동일한 값
describe('CatsService', () => {
  let service: CatsService
  let model: Model<Cat>
  beforeEach(async () => {
    const module: TestingModule = await Test.createTestingModule({
      providers: [
        ConfigService,
        // Model 주입. 
        { provide: getModelToken(Cat.name), useClass: Cat },
      ],
    })
      .compile()
    service = module.get<CatsService>(CatsService)
    model = module.get<Model<CatsDto>>(getModelToken(Cat.name))

reference

0개의 댓글