Nest.js 알아보기 - 컨트롤러

sprinkler dev·2022년 6월 21일
0

Nest.js 알아보기

목록 보기
2/2
post-custom-banner

서론

컨트롤러의 목적은 애플리케이션을 위한 특정 요청들을 받는 것이다.
클라이언트로부터 들어온 HTTP 요청들은 라우팅 메커니즘에 따라서 알맞은 컨트롤러로 분배된다.

Nest에서는 @Controller, @Get, @Post 등 데코레이터를 이용해서 컨트롤러를 구성할 수 있다.

nestcli를 이용해서 CRUD 컨트롤러를 간단히 만들 수 있다.

$ nest g resource [name]

Controller 데코레이터

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

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

@Controller, @Get 데코레이터를 사용하는 예제 코드

@Controller 데코레이터는 관계있는 라우터를 그룹화하는데 사용한다. 데코레이터의 인자로 라우팅 주소를 받는다.
@Controller('cats')라고 작성하면 /cats 주소로 접근하는 모든 요청은 해당 컨트롤러를 거쳐갈 것이다.

Express.js로 따지자면 아래와 같이 만들 수 있다.

app.use('cats', CatsController);

@Get 데코레이터는 get메소드로 들어온 HTTP 요청을 받는 핸들러를 의미한다.

@Controller 데코레이터와 마찬가지로 인자로 라우팅 주소를 받는다. 인자로 아무 값도 넘기지 않으면 '/'로 연결된다.

즉, @Controller('cats') 내부의 @Get()는 /cats 경로로 GET 메소드 HTTP 요청이 들어오는 경우에 실행하는 핸들러가 된다.

만약 @Get('/profile') 애노테이션으로 라우터를 만든다면 /cats/profile 경로로 들어온 HTTP 요청을 처리할 것이다.


Response object

기본적으로 Nest 컨트롤러는 상태코드 200을 반환한다.
Nest는 두 종류의 response 옵션을 제공하는데 아래와 같다.

  • Standard (권장)
    핸들러가 객체 또는 배열인 경우에 자동으로 이를 JSON으로 직렬화한다.
    원시타입(string, number...)인 경우에는 직렬화하지 않고 보낸다.
    상태코드는 항상 기본 200이다. (POST의 경우 201)
    상태코드는 @HttpCode 데코레이터로 설정할 수 있다.

  • Library-specific
    특정 라이브러리의 response 객체를 의미함. (e.g. Express)
    이러한 객체는 @Res 데코레이터를 사용해서 호출한다.

Nest에서도 @Res(), @Next() 등을 호출해서 사용할 수 있다.
이 데코레이터들을 호출하면 standard 옵션은 자동으로 비활성화 된다.
두 옵션을 동시에 사용하려면 @Res({ passthrough: true }) 이렇게 passthrough 옵션을 true로 설정하면 된다.


Request object

핸들러가 클라이언트의 request 객체에 접근할 일이 종종있다.
Nest는 request 객체에 접근할 수 있는 @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';
  }
}

@Req 데코레이터 사용 예시

request 객체 전체가 아니라 클라이언트로부터 전달받은 body나 querystring만 필요한 경우에도 @Body, @Query 데코레이터를 위와 같이 호출하여 사용할 수 있다.


Resources

Nest는 모든 기본 HTTP 메소드를 데코레이터로 제공한다. 이 데코레이터들은 '@nestjs/common' 모듈에 선언되어 있다.
@Get, @Post, @Put, @Delete, @Patch, @Options, @Head가 있으며 추가로 @All 데코레이터로 이 모든 메소드를 핸들링하는 라우터를 만들 수 있다.

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

@Controller('cats')
export class CatsController {
  @Post()
  create(): string {
    return 'This action adds a new cat';
  }

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

POST 메소드 라우팅 예시


Route wildcards

라우트 주소에 와일드카드 문자를 포함할 수 있다.

@Get('ab*cd')
findAll() {
  return 'This route uses a wildcard';
}

여기서 'abcd' 라우트 주소는 'abcd', 'ab_cd', 'abecd' 등과 매치된다.
?, +,
, (, ) 문자를 라우트 주소에 사용할 수 있고 정규표현식에서의 사용법을 일부 포함한다.


Asynchronicity

Nest는 async / await과 RxJS의 observable streams을 지원한다.
async 함수는 반드시 Promise 타입을 반환한다.

// async 함수
@Get()
async findAll(): Promise<any[]> {
  return [];
}

// observable streams 사용
@Get()
findAll(): Observable<any[]> {
  return of([]);
}

Request payloads

위에서 살펴본 POST 메소드 예시 코드를 보면 핸들러가 클라이언트로부터 아무런 값도 받지 않고 있다.

@Body 애노테이션을 이용해서 클라이언트로부터 request body를 받아보자.

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

@Post()
async create(@Body() createCatDto: CreateCatDto) {
  return 'This action adds a new cat';
}

ValidationPipe 기능을 사용해서 클라이언트로부터 받은 값들이 유효한지 검사할 수 있다.


import { Controller, Get, Query, Post, Body, Put, Param, Delete } from '@nestjs/common';
import { CreateCatDto, UpdateCatDto, ListAllEntities } from './dto';

@Controller('cats')
export class CatsController {
  @Post()
  create(@Body() createCatDto: CreateCatDto) {
    return 'This action adds a new cat';
  }

  @Get()
  findAll(@Query() query: ListAllEntities) {
    return `This action returns all cats (limit: ${query.limit} items)`;
  }

  @Get(':id')
  findOne(@Param('id') id: string) {
    return `This action returns a #${id} cat`;
  }

  @Put(':id')
  update(@Param('id') id: string, @Body() updateCatDto: UpdateCatDto) {
    return `This action updates a #${id} cat`;
  }

  @Delete(':id')
  remove(@Param('id') id: string) {
    return `This action removes a #${id} cat`;
  }
}

기본적인 CRUD 컨트롤러 구성


이렇게 만든 컨트롤러를 Nest가 인식할 수 있게 root module에 추가해주어야 한다.

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

@Module({
  controllers: [CatsController],
})
export class AppModule {}
profile
2년차 백엔드 개발자
post-custom-banner

0개의 댓글