providers: Nest의 injector (typedi와 같은)에 의해 인스턴스화되고, 인스턴스들은 이 모듈 안에서 최소한으로 공유된다.
controllers: 해당 모듈에서 정의된, 인스턴스화 되어야 하는 컨트롤러의 모음이다.
imports: 임포트된 모듈들의 리스트이다. 이 리스트의 모듈들은 데코레이터에 사용 중인 모듈에서 필요한 providers를 export 하고 있어야 한다.
exports: providers의 하위 집합으로, 데코레이터를 사용 중인 모듈이 제공받은 Provider의 일부를 내보낼 수 있다. 이는 다른 모듈에서 import 할 때 사용된다.
Nest(NestJS)는 효율적이고 확장 가능한 Node.js 서버 측 애플리케이션을 구축하기 위한 프레임워크입니다.
좀더 쉽게 풀어설명하면, Node.js와 똑같은 기능들을 구현가능하면서 사용자들이 좀더 쉽게 대규모 프로젝트에 활용할수 있도록 규칙을 제공한 프레임 워크입니다 .
TypeScript 로 구축되고 Javascript로 동작됩니다. (우리는 typeScript로 로직 짜면 됩니다!^^)
내부적으로는 Express가 동작됩니다.
Nest는 개발자와 팀이 테스트 가능성이 높고 확장 가능하며 느슨하게 결합되고 유지 관리가 쉬운 애플리케이션을 만들 수 있도록 하는 즉시 사용 가능한 애플리케이션 아키텍처를 제공합니다. 아키텍처는 Angular에서 크게 영감을 받았습니다.
아래 커멘드중 @nestjs/cli는 nestjs를 cli로 실행하게 해주는 설치고 nest를 통해 프로젝트를 생성할수 잇습니다.
npm은 node.js를 설치하시면 사용가능합니다 .
$ npm i -g @nestjs/cli
$ nest new project-name
이제 귀여운 nestjs의 사용법을 간단하게 알아보자.
이 글은 nestjs 공식문서로 이해한 내용과 강의를 듣고 이해한 내용을 합쳐서!! 적었다~~
하나씩 천천히 보자!
아래 명령을 치면 기본적으로 사용할 nestjs프로젝트 폴더가 생성됩니다.
$ nest new project-name
src에 nestjs형식으로 사용될 파일들이 생겻습니다. 파일 하나씩 살펴봅시다.
메인 문을 보면 bootstrap함수에서 NestFactory를 이용해 app라는 인스턴스를 만듭니다. nestjs는 이렇게 만든 하나의 app로 모든 객체들을 관리합니다.
app인스턴스에 다른 객체들을 provider 해서 해당 클래스들을 사용할수 있습니다. 그래서 이렇게 사용하는걸 싱글톤 인스턴스화라고 합니다.
싱글톤이란? : 각 클래스가 하나의 인스턴스만 생성하고, 어떤 프로바이더든지 같은 인스턴스를 공유해 사용하는 패턴
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
await app.listen(3000);
}
bootstrap();
만약 express나 fastify를 사용하고 싶으면 플랫폼을 추가해주어야합니다 . 아래와 같이 추가 할수 잇습니다. (NestExpressApplication,NestFastifyApplication.)
const app = await NestFactory.create<NestExpressApplication>(AppModule);
컨트롤러의 목적은 애플리케이션에 대한 특정 요청을 수신하는 것입니다.
라우팅 메커니즘 은 어떤 컨트롤러가 어떤 요청을 수신하는지 제어합니다.
만드는 방법은 두가지가 있습니다.
아래코드를 실행하면 자동으로 controller가 생성됩니다.
nest g controller cats
@Controller를 사용해 만들수 있습니다.
import { Controller, Get } from '@nestjs/common';
@Controller('cats')
export class CatsController {
@Get()
findAll(): string {
return 'This action returns all cats';
}
}
위의 예제에서 만든 find에 의해 응답이 생성되면 자동으로 json형태로 state: 200 과 'This action returns all cats'가 응답됩니다.
@HttpCode(...)를 통해 응답코드를 바꿀수 있습니다. 응답의 상태 코드@HttpCode(...) 는 201을 사용하는 POST 요청을 제외하고 기본적으로 항상 200입니다 . 핸들러 수준에서 데코레이터를 추가하여 이 동작을 쉽게 변경할 수 있습니다 ( 상태 코드 참조 ).
@Post()
@HttpCode(204)
create() {
return 'This action adds a new cat';
}
핸들러는 종종 클라이언트 요청 세부 정보 에 액세스해야 합니다 .
'@nestjs/common' 라이브러리를 이용해 Req데코레이터를 사용할수있습니다.
req의 더 자세한 설명은 아래 링크에서 확인할수 있습니다.
https://expressjs.com/en/api.html#req
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';
}
}
express타이핑 을 활용 하려면(위의 request: Request매개변수 예제에서와 같이) @types/express패키지를 설치하십시오.
요청 객체는 HTTP 요청을 나타내며 요청 쿼리 문자열, 매개변수, HTTP 헤더 및 본문에 대한 속성을 가지고 있습니다
추가로 데코레이터를 이용해 요청에들어온 데이터들을 받아올수 있습니다.
사용자 지정 응답 헤더를 지정하려면 @Header()데코레이터 또는 라이브러리별 응답 개체를 사용하고 res.header()직접 호출할 수 있습니다.
@Post()
@Header('Cache-Control', 'none')
create() {
return 'This action adds a new cat';
}
@Controller({ host: 'admin.example.com' })
export class AdminController {
@Get()
index(): string {
return 'Admin page';
}
}
비동기하는 방법은 두가지가 있습니다.
1. async 이용
@Get()
async findAll(): Promise<any[]> {
return [];
}
@Get()
findAll(): Observable<any[]> {
return of([])
}
나는 async를 선호한다..
POST 라우트 핸들러가 클라이언트의 payload를 사용하려면 먼저 DTO(Data Transfer Object)를 정의해야 한다.
provider 와 Injectable
의존성이란? 다른 파일에서 클래스나 서비스 등 함수나 객체를 사용하기위해 의존성이라는걸 사용한다.
@injectable을 사용해서 의존성으로 사용할건지 정하고 provider에다가 의존성을 사용할 클래스를 저장해두면도니다.