[공식문서] Controllers

Haeseo Lee·2023년 4월 7일
0

NestJS 공식문서

목록 보기
1/4
post-thumbnail

공식문서 공부하기
https://docs.nestjs.com/controllers

필요한 부분만 발췌해서 정리

Controller 정의

controller는 들어오는 요청을 처리하고 client에게 응답을 반환한다.

controller의 목적은 application으로 들어오는 특정한 요청을 받기 위한 것이다. routing 매커니즘이 어떤 controller가 특정 요청을 처리해야 할지를 결정해준다. 보통은 각각의 controller는 한 개 이상의 route를 가지고 있고, 각 route는 제각기 다른 역할을 수행한다.

Controller 사용

controller를 만들기 위해 class와 데코레이터를 사용한다. 데코레이터로 class와 필요한 metadata를 연관시키고, Nest가 routing map(요청별로 controller 매핑)을 생성할 수 있게끔 해준다.

@Controller() 데코레이터 안에 경로명을 넣어서 해당 경로로 들어오는 요청을 controller에서 처리할 수 있다.

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

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

Nest는 표준 HTTP 메서드에 대한 데코레이터를 제공한다
@Get(), @Post(), @Put(), @Delete(), @Patch(), @Options(), @Head().

Nest에서 Response를 만드는 2가지 방식

1) standard(recommended)
request handler가 javascript 객체나 배열을 반환할 경우, 자동으로 JSON으로 변환된다.
그러나 javascript 원시 타입(e.g. string, number, boolean)은 변환 없이 그대로 전달된다.
POST 요청을 제외하고(201), 모든 응답의 status code는 200이다.
-> 바꾸고 싶다면 handler-level에서 @HttpCode() 데코레이터를 사용하면 된다.

2) Library-specific
특정 라이브러리(e.g. Express)의 response 객체를 직접 사용할 수 있다.
예를 들어, Express의 response객체를 사용하려면 handler method에 @Res() 데코레이팅된 response객체를 매개변수로 넣어주고 , 응답을 response.status(200).send()와 같이 구성해서 사용할 수 있다.

@Get()
findAll(@Res() res: Response) {
	res.status(HttpStatus.OK).json([]);
}

@Res()@Next()와 같이 library-specific한 response를 사용하게 될 경우, Nest가 자동으로 이를 감지해준다. 그러나 한 route에서 standard 방식과 library-specific 방식을 동시에 사용할 경우, standard 방식은 자동으로 비활성화된다. 쿠키나 헤더 설정을 위해 response 객체를 사용하는 것 외에 나머지는 그대로 두고 싶다, 라고 한다면 passthrough 옵션을 true로 줘야 한다.

@Get()
findAll(@Res({ passthrough: true }) res: Response) {
	res.status(HttpStatus.OK).json([]);
}

Request

client에서 보내온 request의 상세한 부분을 뜯어보고자 한다면, Nest에서 제공하는 @Req() 데코레이터를 사용할 수 있다. @Req() 데코레이터로 가져온 request 객체에는 쿼리 스트링, 파라미터, HTTP 헤더, body가 포함되어 있다. 그러나 보통 해당 속성들을 가져오고자 한다면 @Body(), @Query(), @Param() 등의 이미 제공되어 있는 데코레이터를 사용한다.

@Request(), @Req()req
@Response(), @Res()*res
@Next()next
@Session()req.session
@Param(key?: string)req.params / req.params[key]
@Body(key?: string)req.body / req.body[key]
@Query(key?: string)req.query / req.query[key]
@Headers(name?: string)req.headers / req.headers[name]
@Ip()req.ip
@HostParam()req.hosts

DTO

DTO(Data Transfer Object)는 네트워크상에서 데이터가 어떻게 전송될지를 정의하는 객체이다. Typescript에서는 classinterface를 사용하여 DTO 스키마를 만들 수 있다.
다만 Nest는 class를 더 추천한다. 왜냐하면 transpile(ts->js) 중에 사라져서 runtime에서 참조할 수 없는 interface와는 달리 class는 javascript ES6 표준이라 컴파일이 가능하기 때문이다.
특히 runtime에서 metadata에 접근해야 하는 Pipe와 같은 애들은 class로 정의를 해주어야 한다.

export class CreateCatDto {
  name: string;
  age: number;
  breed: string;
}
@Post()
async create(@Body() createCatDto: CreateCatDto) {
  return 'This action adds a new cat';
}

의존성 주입

만들어진 controller가 Nest에서 인식되고 사용되게 하려면 Module의 controllers에 등록해줘야 한다. 그래야 module과 함께 controller가 mount될 수 있다.

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

@Module({
  controllers: [CatsController],
})
export class AppModule {}
profile
잡생각 많은 인간

0개의 댓글