Programming/Nest.js

[Nest.js 기초] 설치와 controller

리버김 2022. 12. 16.

설치

npm i -g @nestjs/cli
nest new 프로젝트-명

서버 실행(yarn 기준)

서버 실행: yarn start

dev 모드: yarn start:dev

프로젝트 디렉토리와 기본 요소 살펴보기

scr 폴더 안의 core 파일들

  • app.controller.ts: 단일 경로가 있는 기본 컨트롤러(MVC 패턴에서의 컨트롤러. Django에서의 View)
  • app.controller.spec.ts 컨트롤러를 위한 유닛 테스트
  • app.module.ts: 애플리케이션의 루트 모듈
  • app.service.ts: 기본 서비스
  • main.ts: 핵심 기능인 NestFactory를 사용하여 nest application instance를 생성하는 시작 파일

main.ts

import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  await app.listen(3000);
}
bootstrap();
  • main.ts는 application을 bootstrap하는 비동기 함수를 포함한다.
    • NestFactory Class: Nest application을 생성하게 해주는 정적 메서드를 제공한다.
    • create(): INestApplication인터페이스를 수행하는 applicatioin 객체를 반환한다.

Controller

controller는 들어오는 요청을 처리하고, 응답을 반환한다.(Django의 View 파일)

우선 applicatioin의 특정 요청을수신하고, Routing 메커니즘이 어떤 controller에 어떤 요청을 수신할지를 조정한다.

종종 각 controller에 두 가지 이상의 경로가 존재할 수 있다.

 

기본 controller를 만들기 위해 classdecorator를 사용한다.decorator는 class를 필수 meta data와 연결하고, Nest가 routing map(요청을 해당 컨트롤러로 연결)을 생성하도록 한다.

 

Routing

@Controller() decorater: 기본 컨트롤러를 정의하는 데 요구되는 기본 decorator다. 관련 경로를 쉽게 그룹화하고, 반복적인 코드를 최소화할 수 있다.

 

예시

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

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

@Get(): HTTP 요청 decorator

 

controller에서 선언한 'cats'와 findAll()에서 선언된 @Get decorator가 아무 경로를 연결하지 않았으므로 최종적으로 GET '/cats' 요청을 이 핸들러에 매핑한다.

 

즉, 위 예제에서 @Get('profile')일 경우 GET '/cats/profile'로 매핑된다.

 

Request Object

Nest는 요청 객체에 대한 엑세스를 제공한다.

핸들러에 @Req() decorator를 추가하여 요청 객체에 접근할 수 있다.

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

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

요청 객체는 query string, parameterrs, HTTP headers, body 같은 속성을 가지고 있다.

대부분의 경우 이러한 속성을 수동으로 가져올 필요 없이 Nest에서 제공하는 전용 decorator를 사용하면 된다.

decorator property
   
@Request(), @Req() req
@Response(), @Res() res
@Next() next
@Session() req.session
@Param(key?: string) req.params, req.params[key]
@Query(key?: string) req.query, req.query[key]
@Ip() req.ip
@HostParam() req.hosts

@Response(), @Res() 를 사용할 경우 Nest 는 해당 핸들러에 대해 Library-specific mode 로 설정하게 되고 이 경우에 응답을 반환해야 할 필요가 있다.

즉, 이 경우 일종의 응답 (res.send, res.json 등) 을 반환해야 하고 그렇지 않으면 서버가 중단된다.

 

모든 고양이를 가져오는 endpoint 이외에 생성 할 수 있는 create endpoint를 만들어 보자. @Post() decorator 를 사용하면 된다.

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

@Controller('cats')
export class CatsController {
  @Post()
  createCat(): string {
    return 'create cat';
  }

  @Get()
  findAll(@Req() req: Request): string {
    return 'return all cats';
  }
}

표준 HTTP methods를 decorator 로 제공한다.(@Get(), @Post(), @Put(), @Delete(), @Patch(), @Options(), @Head())

@All() 은 위 모두를 처리하는 endpoint를 정의한다.

 

Status Code

기본적으로 상태 코드는 POST 요청을 제외하고는 항상 200이다.

@HttpCode() decorator를 통해 핸들러 레벨에서 쉽게 바꿀 수 있다.

  @Put()
  @HttpCode(204)
  modifyCat(): string {
    return 'modify cat';
  }

Headers

custom response header를 만들기 위해 @Header() decorator나 library-specific response 객체를 사용할 수 있다.

@Post()
@Header('Cache-Control', 'none')
create() {
  return 'This action adds a new cat';
}

Redirection

응답을 특정 URL로 redirection하려면 @Redirect() decorator나 library-specific response 객체(res.redirect())를 사용할 수 있다.

@Redirect() decorator는 optional한 2개의 arguments를 가진다(URL, statusCode)

statusCode의 default 값은 302이다.

@Get()
@Redirect('https://nestjs.com', 301)

때때로 동적으로 statusCode나 URL을 결정해야 하는 경우에는, 다음과 같은 형식으로 반환하면 가능하다.

{
  "url": string,
  "statusCode": number
}
@Get('docs')
@Redirect('https://docs.nestjs.com', 302)
getDocs(@Query('version') version) {
  if (version && version === '5') {
    return { url: 'https://docs.nestjs.com/v5/' };
  }
}

Route Parameters

매개변수가 있는 경로를 정의하기 위해 경로에 route parameter token을 추가하여 동적 값을 찾아낼 수 있다.

  @Get(':id')
  findCatById(@Param('id') id: string): string {
    console.log(id);
    return `return cat's id : ${id}`;
  }

Request Payloads

위 POST 예제에서는 route handler가 어떠한 client params를 받지 않았다.

@Body() decorator를 추가하여 고치면 되고, class를 사용하여 DTO(Data Transfer Object)를 만드는 것을 추천한다.

 

CreateCatDto class

export class CreateCatDto {
  name: string;
  age: number;
  breed: string;
}

CatsController에서 새로 생성한 DTO를 사용할 수 있다.

@Post()
async createcat(@Body() createCatDto: CreateCatDto) {
  return 'create cat by using CreateCatDto';
}

 

Controller 반영하기

controller가 완전히 정의되고 나서도, Nest는 CatsController가 존재하는지 알지 못하며, 결과적으로 이 클래스의 인스턴스를 생성하지 않는다. controller가 항상 module에 속하므로, @Module() decorator 내에 controller 배열을 포함한다.

 

아래 예시를 보면 @Module() decorator를 활용해 module class에 metadata를 넣었으며, 이제 Nest가 mount되어야 하는 컨트롤러를 쉽게 반영할 수 있다.

 

app.module.ts

import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { CatsController } from './cats/cats.controller';
​
@Module({
  imports: [],
  controllers: [AppController, CatsController],
  providers: [AppService],
})
export class AppModule {}

'Programming > Nest.js' 카테고리의 다른 글

[Nest.js] API 만들어 보기(유저 등록)  (0) 2022.12.19
Nest.js란?  (0) 2022.12.16

댓글