[NestJS] Controller(6) - Request payloads, Getting up and running, Library-specific approach

cabbage·2023년 4월 25일
0

NestJS

목록 보기
10/17
post-thumbnail

NestJS 공식문서의 Controller 개념 공부 6번째 포스트로, Controller의 Request payloads, Getting up and running, Library-specific approach 주제로 작성한다.

Request payloads

타입스크립트를 사용하는 경우, DTO(Data Transfer Object) 스키마를 정의해야 한다. DTO는 네트워크를 통해 데이터가 전송되는 방법을 정의하는 객체이다.

타입스크립트의 인터페이스 또는 간단한 클래스를 사용하여 DTO 스키마를 정의할 수 있다. 클래스를 사용하는 것을 추천하는데, 그 이유는 클래스는 자바스크립트 ES6 표준의 한 부분이므로 컴파일된 자바스크립트의 실제 엔티티로 보존되기 때문이다. 반면에, 타입스크립트 인터페이스는 컴파일 과정에서 제거되므로 Nest가 런타임에 참조할 수 없다. 이 사실은 Pipe와 같은 기능들이 런타임에서 변수의 메타타입에 액세스할 때 추가적인 가능성을 가능하게 해주기 때문에 중요하다.

DTO로 사용할 CreateCatDto 클래스는 아래와 같다.

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

CreateCatDto 클래스는 세 개의 프로퍼티를 갖는다. 이제 CatsController 내부에서 새롭게 생성한 DTO를 사용할 수 있다.

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

Getting up and running

CatsController가 정의되어 있더라도, Nest는 CatController가 존재하는지 아직 모르는 상태이므로 이 클래스의 인스턴스를 생성하지 않게 된다.

컨트롤러는 항상 모듈에 속하는데, @Module() 데코레이터 내부의 controllers 배열에 컨트롤러를 추가하기 때문이다. 아직 루트 AppModule를 제외하고 다른 모듈을 정의하지 않았기 때문에, CatsControllerAppModule에 추가한다.

@Module({
  controllers: [CatsController],
})
export class AppModule {}

@Module() 데코레이터를 사용하여 모듈 클래스에 메타데이터를 추가하였다. Nest는 이제 어떤 컨트롤러가 마운트되어야 하는지를 쉽게 알 수 있다.

Library-specific approach

지금까지는 응답을 조작하는 Nest의 표준 방식에 대해 논의하였다. 응답을 조작하는 두 번째 방식은 라이브러리-특정 응답 객체를 사용하는 것이다. 특정 응답 객체를 주입하려면, @Res() 데코레이터를 사용해야 한다. CatsController를 아래와 같이 수정해, 기존 방식과 차이점을 비교한다.

@Controller('cats')
export class CatsController {
  // 응답 객체 사용 방식
  @Post()
  create(@Res() res: Response) {
    res.status(HttpStatus.CREATED).send();
  }
  
  // 응답 객체 사용 방식
  @Get()
  findAll(@Res() res: Response) {
     res.status(HttpStatus.OK).json([]);
  }
}

이 방식이 응답 객체에 대한 전체적인 제어를 제공하기 때문에 좀 더 유연하다는 것은 사실이지만, 신중하게 사용해야 한다. 일반적으로 이 방식은 덜 명확하고 몇 가지 단점을 가지고 있다. 주요한 단점은 코드가 플랫폼-종속적(라이브러리가 응답 객체에 대해 다른 API를 가지고 있을 수 있음)이고 테스트하기 어렵다는 것이다(응답 객체를 mocking해야 함).

또한 위 예제에서는, 인터셉터와 @HttpCode() / @Header() 데코레이터와 같이 Nest 표준 응답 핸들링에 의존하는 Nest 기능들과의 호환성을 잃어버리게 된다. passthrough 옵션을 true로 설정해 이것을 수정할 수 있다.

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

이제 기본 응답 객체와 상호 작용할 수 있게 되었다. 나머지는 Nest에게 맡기면 된다.

참고

profile
캐비지 개발 블로그입니다. :)

0개의 댓글