first steps

$ npm i -g @nestjs/cli
$ nest new project-name

nest 프로젝트 시작하기

 

 

nest generate module cat
nest g controller cat
nest g service cat​

nest generate (nest g)를 통해 module, controller, service를 간편하게 생성할 수 있다.

 

 

 

controller

import { Controller, Get } from '@nestjs/common';

@Controller('cats')
export class CatsController {
  @Get()
  findAll(): string {
    return 'This action returns all cats';
  }
}

 

@Controller() decorator 안에 있는 주소로 라우팅된다.

@Get()안에 세부 라우팅 주소를 적을 수도 있다. 현재는 기본값 

/cats get 메서드가 적용 된다.

 

 

import { Controller, Get, Req } from '@nestjs/common';
import { Request } from 'express';

@Controller('cats')
export class CatsController {
  @Get()
  findAll(@Req() request: Request): string {
    return 'This action returns all cats';
  }
}

Request를 활용하기 위해서는 @Req()를 사용한다.

 

 

 

service

import { Injectable } from '@nestjs/common';
import { Cat } from './interfaces/cat.interface';

@Injectable()
export class CatsService {
  private readonly cats: Cat[] = [];

  create(cat: Cat) {
    this.cats.push(cat);
  }

  findAll(): Cat[] {
    return this.cats;
  }
}

controller에서 활용하기 위한 로직이 담긴 service

controller에서 활용하기위해 @Injectable() 사용했다.

 

 

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

cat interface

 

 

 

import { Controller, Get, Post, Body } from '@nestjs/common';
import { CreateCatDto } from './dto/create-cat.dto';
import { CatsService } from './cats.service';
import { Cat } from './interfaces/cat.interface';

@Controller('cats')
export class CatsController {
  constructor(private catsService: CatsService) {}

  @Post()
  async create(@Body() createCatDto: CreateCatDto) {
    this.catsService.create(createCatDto);
  }

  @Get()
  async findAll(): Promise<Cat[]> {
    return this.catsService.findAll();
  }
}

controller에서 Injectable() service를 사용하기위해 constructor에 담아주었다. (service is injected.)

 

constructor(private catsService: CatsService) {}

constructor를 통해 의존성 주입!

싱글톤 기반으로 new 를 사용하지 않았다.

 

 

 

 

module

import { Module } from '@nestjs/common';
import { CatsController } from './cats/cats.controller';
import { CatsService } from './cats/cats.service';

@Module({
  controllers: [CatsController],
  providers: [CatsService],
})
export class CatModule {}

module에 @Module()을 활용하여 controllers, providers를 반영했다.

 

 

 

providers nest injector (의존성 주입하는 내부 모듈) 에 의해 인스턴스화 되고 해당 모듈 전체에서 공유될 수 있는 Providers
controllers 인스턴스화 되어야 하는 해당 모듈에 정의된 controllers
imports 해당 모듈에 필요한 모듈의 집합. providers를 내보내서 활용하기 위해 가져온 modules
exports 해당 모듈에서 제공하는 providers 의 부분집합. 다른 모듈에서 사용할 수 있는 providers를 제공하도록 export

@Module()에는 providers, controllers, imports, exports가 있다.

 

 

 

import { Module } from '@nestjs/common';
import { CatsModule } from './cats/cats.module';

@Module({
  imports: [CatModule],
})
export class AppModule {}

메인 app.module (루트 모듈)에 catModule을 가져오기 위해 imports에 적용했다.

 

 

 

Shared Module

Nest에서 모듈은 기본적으로 싱글톤(singleton)이기 때문에

여러 모듈간에 쉽게 공급자의 동일한 인스턴스를 공유 할 수 있다.

모든 모듈은 자동으로 shared module이다. 공유가 가능한 모듈이라는 뜻이고 생성되면 모든 모듈에서 재사용할 수 있다.

 

 

 

import { Module } from '@nestjs/common';
import { CatsController } from './cats.controller';
import { CatsService } from './cats.service';

@Module({
  controllers: [CatsController],
  providers: [CatsService],
  exports: [CatsService]
})
export class CatsModule {}

다른 모듈에서도 CatsService 인스턴스를 공유하며 사용하도록 exports 에 추가했다.

 

 

@Module({
  imports: [CommonModule],
  exports: [CommonModule],
})
export class CoreModule {}

import -> export 받아서 노출하는, re-exporting도 가능하다.

 

 

 

Global Modules

모든 곳에서 동일한 모듈을 가져와야한다면 application 어디서나 사용할수 있는 것이 필요하다.

@Global() 데코레이터를 활용해서 전역모듈을 만들 수 있다.

 

import { Module, Global } from '@nestjs/common';
import { CatsController } from './cats.controller';
import { CatsService } from './cats.service';

@Global()
@Module({
  controllers: [CatsController],
  providers: [CatsService],
  exports: [CatsService],
})
export class CatModule {}

 

 

 

Dynamic Modules

동적 모듈

providers를 동적으로 등록하고 구성할 수 있는 customizing module을 쉽게 만들 수 있다.

import { Module, DynamicModule } from '@nestjs/common';
import { createDatabaseProviders } from './database.providers';
import { Connection } from './connection.provider';

@Module({
  providers: [Connection],
})
export class DatabaseModule {
  static forRoot(entities = [], options?): DynamicModule {
    const providers = createDatabaseProviders(options, entities);
    return {
      module: DatabaseModule,
      providers: providers,
      exports: providers,
    };
  }
}

forRoot() 메서드는 promise를 통해 동적모듈을 동기식, 또는 비동기식으로 반환할 수 있다.

동적 모듈이 반환하는 속성은 @Module() 데코레이터에 정의된 모듈의 기본적인 메타데이터를 재정의(override)하지 않고 확장한다.

이렇게하면 정적으로 선언된 Module()의 provides, 동적으로 생성된 providers 모두 모듈에서 export 된다.

 

 

return {
  global: true,
  module: DatabaseModule,
  providers: providers,
  exports: providers,
}

전역 모듈로 동작하려면 global 속성을 포함해서 return 한다.

 

 

import { Module } from '@nestjs/common';
import { DatabaseModule } from './database/database.module';
import { User } from './users/entities/user.entity';

@Module({
  imports: [DatabaseModule.forRoot([User])],
  exports: [DatabaseModule],
})
export class AppModule {}

동적모듈은 위와같이 imports, exports  활용할 수 있다.