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 활용할 수 있다.
'Back-end > NestJS' 카테고리의 다른 글
Node.js 프레임워크 비교 - Express, Nest.js 직접 사용해보며 느낀점 (0) | 2023.11.22 |
---|---|
nestJS hot reload 설정 (0) | 2023.09.07 |
dynamoose + nestJS 설정 및 CRUD (0) | 2023.09.06 |