가을기 Workspace

NestJS mongodb module 본문

개발/nodejs

NestJS mongodb module

가을기_ 2021. 5. 9. 21:10

 

 

 

 

 

Docker-compose로 mongodb 띄우기

docker-compose.yml

# Use root/example as user/password credentials
version: '3.1'

services:

  mongo:
    image: mongo
    restart: always
    environment:
      MONGO_INITDB_ROOT_USERNAME: root
      MONGO_INITDB_ROOT_PASSWORD: example

  mongo-express:
    image: mongo-express
    restart: always
    ports:
      - 8081:8081
    environment:
      ME_CONFIG_MONGODB_ADMINUSERNAME: root
      ME_CONFIG_MONGODB_ADMINPASSWORD: example
      
      
      
  $ docker-compose up -d

 

 

참고: https://faun.pub/managing-mongodb-on-docker-with-docker-compose-26bf8a0bbae3

 

 

NestJS에서 연동하기

mongoose를 활용한다.

$ npm install --save @nestjs/mongoose mongoose



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

@Module({
  imports: [MongooseModule.forRoot('mongodb://localhost/nest')],
})
export class AppModule {}

Module을 불러오며 connection 정보를 넣어준다.

MongooseModule.forRoot는 mongoose.connect와 같은 config를 쓴다고 보면 된다.

참고: https://mongoosejs.com/docs/connections.html

 

 

 

Model injection

Mongoose에서 모든건 schema다.

각 schema가 mongodb collection과 document 형태를 결정한다.

Schema는 Models를 정의하고, Models는 document 생성/삭제를 담당한다.

 

이 Schema를 decorator로 손쉽게 만들 수 있다.

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 decorator는 모두가 예상하는 대로 Schema를 정의한다.

Prop decorator는 document의 property를 의미한다.

@Prop([String])
tags: string[];

mongodb type을 따로 줘야할때 정의할 수 있다.

 

 

@Prop({ required: true })
name: string;

필수 prop인지 아닌지도 option으로 줄 수 있다.

 

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;

다른 collection을 참조하는 id의 경우 type을 ObjectId,로, ref를 collection 이름으로 주면 된다.

 

 

@Prop({ type: [{ type: mongoose.Schema.Types.ObjectId, ref: 'Owner' }] })
owner: Owner[];

collection 안에 여러 document를 참조하는 경우 이렇게.

 

 

@Prop(raw({
  firstName: { type: String },
  lastName: { type: String }
}))
details: Record<string, any>;

property를 annonymous 하게 정의하는 경우

 

 

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

decorator 없이 mongoose 그대로 쓰는 것도 가능하다.

 

Dependency Injection

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 {}

이렇게 만들어진 Schema를 NestJs에 등록해야한다.

 

 

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();
  }
}

NestJS에 등록하면 Provider에서 Inject 받아 쓸 수 있게 된다.

 

 

Connection

import { Injectable } from '@nestjs/common';
import { InjectConnection } from '@nestjs/mongoose';
import { Connection } from 'mongoose';

@Injectable()
export class CatsService {
  constructor(@InjectConnection() private connection: Connection) {}
}

Connection 객체로 native API 호출을 하고 싶으면 InjectConnection decorator로 받을 수 있다.

 

 

Multiple Database

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

@Module({
  imports: [
    MongooseModule.forRoot('mongodb://localhost/test', {
      connectionName: 'cats',
    }),
    MongooseModule.forRoot('mongodb://localhost/users', {
      connectionName: 'users',
    }),
  ],
})
export class AppModule {}

mongodb를 여러개 쓰는 경우 connectionName을 각각 따로 줘야한다.

 

 

@Module({
  imports: [
    MongooseModule.forFeature([{ name: Cat.name, schema: CatSchema }], 'cats'),
  ],
})
export class AppModule {}

모듈에서 connection을 부르려할때 connectionName을 같이 줘야한다.

 

 

 

import { Injectable } from '@nestjs/common';
import { InjectConnection } from '@nestjs/mongoose';
import { Connection } from 'mongoose';

@Injectable()
export class CatsService {
  constructor(@InjectConnection('cats') private connection: Connection) {}
}

Injection 받을 때 역시 connectionName으로.

 

'개발 > nodejs' 카테고리의 다른 글

Node.js Philosophy - nodejs의 디자인 철학  (0) 2021.09.09
Typescript로 object 초기화  (0) 2021.06.16
NestJS module  (0) 2021.05.09
NestJS provider  (0) 2021.05.09
NestJS controller  (0) 2021.05.09
Comments