MongoDB (Mongoose)

MongoDB (Mongoose)

κ²½κ³  이 κΈ°μ‚¬μ—μ„œλŠ” μ»€μŠ€ν…€ μ»΄ν¬λ„ŒνŠΈλ₯Ό μ‚¬μš©ν•˜μ—¬ μ²˜μŒλΆ€ν„° Mongoose* νŒ¨ν‚€μ§€λ₯Ό 기반으둜 DatabaseModule을 μž‘μ„±ν•˜λŠ” 방법을 ν•™μŠ΅ν•©λ‹ˆλ‹€. 결과적으둜 이 μ†”λ£¨μ…˜μ—λŠ” μ¦‰μ‹œ μ‚¬μš© κ°€λŠ₯ν•œ μ „μš© @nestjs/mongoose νŒ¨ν‚€μ§€λ₯Ό μ‚¬μš©ν•˜μ—¬ μƒλž΅ν•  μˆ˜μžˆλŠ” λ§Žμ€ μ˜€λ²„ ν—€λ“œκ°€ ν¬ν•¨λ˜μ–΄ μžˆμŠ΅λ‹ˆλ‹€. μžμ„Έν•œ λ‚΄μš©μ€ μ—¬κΈ°λ₯Ό μ°Έμ‘°ν•˜μ‹­μ‹œμ˜€.

Mongoose은 κ°€μž₯ μΈκΈ°μžˆλŠ” MongoDB 객체 λͺ¨λΈλ§ λ„κ΅¬μž…λ‹ˆλ‹€.

Getting started

이 라이브러리둜 λͺ¨ν—˜μ„ μ‹œμž‘ν•˜λ €λ©΄ ν•„μš”ν•œ λͺ¨λ“  쒅속성을 μ„€μΉ˜ν•΄μ•Όν•©λ‹ˆλ‹€.

@@filename()
$ npm install --save mongoose
$ npm install --save-dev @types/mongoose
@@switch
$ npm install --save mongoose

κ°€μž₯ λ¨Όμ €ν•΄μ•Ό ν•  일은 connect()ν•¨μˆ˜λ₯Ό μ‚¬μš©ν•˜μ—¬ λ°μ΄ν„°λ² μ΄μŠ€μ™€ μ—°κ²°ν•˜λŠ” κ²ƒμž…λ‹ˆλ‹€. connect()ν•¨μˆ˜λŠ” Promiseλ₯Ό λ°˜ν™˜ν•˜λ―€λ‘œ async providerλ₯Ό λ§Œλ“€μ–΄μ•Ό ν•©λ‹ˆλ‹€.

@@filename(database.providers)
import * as mongoose from 'mongoose';

export const databaseProviders = [
  {
    provide: 'DATABASE_CONNECTION',
    useFactory: (): Promise<typeof mongoose> =>
      mongoose.connect('mongodb://localhost/nest'),
  },
];
@@switch
import * as mongoose from 'mongoose';

export const databaseProviders = [
  {
    provide: 'DATABASE_CONNECTION',
    useFactory: () => mongoose.connect('mongodb://localhost/nest'),
  },
];

info 힌트 λͺ¨λ²” 사둀에 따라 * .providers.ts 접미사가 μžˆλŠ” λ³„λ„μ˜ 파일둜 μ‚¬μš©μž 지정 κ³΅κΈ‰μžλ₯Ό μ„ μ–Έν–ˆμŠ΅λ‹ˆλ‹€.

그런 λ‹€μŒ μ‘μš© ν”„λ‘œκ·Έλž¨μ˜ λ‚˜λ¨Έμ§€ 뢀뢄에 λŒ€ν•΄ μ•‘μ„ΈμŠ€ν•  수 μžˆλ„λ‘ μ΄λŸ¬ν•œ κ³΅κΈ‰μžλ₯Ό λ‚΄ λ³΄λ‚΄μ•Όν•©λ‹ˆλ‹€.

@@filename(database.module)
import { Module } from '@nestjs/common';
import { databaseProviders } from './database.providers';

@Module({
  providers: [...databaseProviders],
  exports: [...databaseProviders],
})
export class DatabaseModule {}

이제 @Inject() λ°μ½”λ ˆμ΄ν„°λ₯Ό μ‚¬μš©ν•˜μ—¬ Connection 객체λ₯Ό μ£Όμž…ν•  수 μžˆμŠ΅λ‹ˆλ‹€. Connection 비동기 κ³΅κΈ‰μžμ— μ˜μ‘΄ν•˜λŠ” 각 ν΄λž˜μŠ€λŠ” Promiseκ°€ ν•΄κ²° 될 λ•ŒκΉŒμ§€ κΈ°λ‹€λ¦½λ‹ˆλ‹€.

Model injection

Mongooseλ₯Ό μ‚¬μš©ν•˜λ©΄ λͺ¨λ“  것이 μŠ€ν‚€λ§ˆμ—μ„œ νŒŒμƒλ©λ‹ˆλ‹€. CatSchemaλ₯Ό μ •μ˜ ν•΄ λ΄…μ‹œλ‹€ :

@@filename(schemas/cats.schema)
import * as mongoose from 'mongoose';

export const CatSchema = new mongoose.Schema({
  name: String,
  age: Number,
  breed: String,
});

CatsSchemaλŠ” cats 디렉토리에 μ†ν•©λ‹ˆλ‹€. 이 λ””λ ‰ν† λ¦¬λŠ” CatsModule을 λ‚˜νƒ€λƒ…λ‹ˆλ‹€.

이제 λͺ¨λΈ κ³΅κΈ‰μžλ₯Ό λ§Œλ“€ μ°¨λ‘€μž…λ‹ˆλ‹€.

@@filename(cats.providers)
import { Connection } from 'mongoose';
import { CatSchema } from './schemas/cat.schema';

export const catsProviders = [
  {
    provide: 'CAT_MODEL',
    useFactory: (connection: Connection) => connection.model('Cat', CatSchema),
    inject: ['DATABASE_CONNECTION'],
  },
];
@@switch
import { CatSchema } from './schemas/cat.schema';

export const catsProviders = [
  {
    provide: 'CAT_MODEL',
    useFactory: (connection) => connection.model('Cat', CatSchema),
    inject: ['DATABASE_CONNECTION'],
  },
];

μ•Œλ¦Ό μ‹€μ œ μ‘μš© ν”„λ‘œκ·Έλž¨μ—μ„œλŠ” 맀직 λ¬Έμžμ—΄μ„ ν”Όν•΄μ•Όν•©λ‹ˆλ‹€. CAT_MODELκ³Ό DATABASE_CONNECTION은 뢄리 된 constants.ts νŒŒμΌμ— 보관해야 ν•©λ‹ˆλ‹€.

이제 @Inject() λ°μ½”λ ˆμ΄ν„°λ₯Ό μ‚¬μš©ν•˜μ—¬ CAT_MODEL을 CatsService에 μ‚½μž…ν•  수 μžˆμŠ΅λ‹ˆλ‹€ :

@@filename(cats.service)
import { Model } from 'mongoose';
import { Injectable, Inject } from '@nestjs/common';
import { Cat } from './interfaces/cat.interface';
import { CreateCatDto } from './dto/create-cat.dto';

@Injectable()
export class CatsService {
  constructor(
    @Inject('CAT_MODEL')
    private readonly catModel: Model<Cat>,
  ) {}

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

  async findAll(): Promise<Cat[]> {
    return await this.catModel.find().exec();
  }
}
@@switch
import { Injectable, Dependencies } from '@nestjs/common';

@Injectable()
@Dependencies('CAT_MODEL')
export class CatsService {
  constructor(catModel) {
    this.catModel = catModel;
  }

  async create(createCatDto) {
    const createdCat = new this.catModel(createCatDto);
    return await createdCat.save();
  }

  async findAll() {
    return await this.catModel.find().exec();
  }
}

μœ„μ˜ μ˜ˆμ—μ„œ μš°λ¦¬λŠ” Cat μΈν„°νŽ˜μ΄μŠ€λ₯Ό μ‚¬μš©ν–ˆμŠ΅λ‹ˆλ‹€. 이 μΈν„°νŽ˜μ΄μŠ€λŠ” λͺ½κ΅¬μŠ€ νŒ¨ν‚€μ§€μ—μ„œ Documentλ₯Ό ν™•μž₯ν•©λ‹ˆλ‹€:

import { Document } from 'mongoose';

export interface Cat extends Document {
  readonly name: string;
  readonly age: number;
  readonly breed: string;
}

λ°μ΄ν„°λ² μ΄μŠ€ 연결은 λΉ„λ™κΈ°μ΄μ§€λ§Œ NestλŠ” μ΅œμ’… μ‚¬μš©μžκ°€ 이 ν”„λ‘œμ„ΈμŠ€λ₯Ό μ™„μ „νžˆ λ³Ό 수 μ—†λ„λ‘ν•©λ‹ˆλ‹€. CatModel ν΄λž˜μŠ€λŠ” db 연결을 기닀리고 있으며 CatsServiceλŠ” λͺ¨λΈμ„ μ‚¬μš©ν•  μ€€λΉ„κ°€ 될 λ•ŒκΉŒμ§€ μ§€μ—°λ©λ‹ˆλ‹€. 각 ν΄λž˜μŠ€κ°€ μΈμŠ€ν„΄μŠ€ν™” 되면 전체 μ‘μš© ν”„λ‘œκ·Έλž¨μ„ μ‹œμž‘ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

λ§ˆμ§€λ§‰CatsModule은 λ‹€μŒκ³Ό κ°™μŠ΅λ‹ˆλ‹€.

@@filename(cats.module)
import { Module } from '@nestjs/common';
import { CatsController } from './cats.controller';
import { CatsService } from './cats.service';
import { catsProviders } from './cats.providers';
import { DatabaseModule } from '../database/database.module';

@Module({
  imports: [DatabaseModule],
  controllers: [CatsController],
  providers: [
    CatsService,
    ...catsProviders,
  ],
})
export class CatsModule {}

warning 힌트 CatsModule을 루트 ApplicationModule둜 κ°€μ Έ μ˜€λŠ” 것을 μžŠμ§€ λ§ˆμ‹­μ‹œμ˜€.

Last updated

Was this helpful?