내일배움캠프 TIL (230320): NestJS DTO 사용 시 주의하기

Jiumn·2023년 4월 1일
0

[NestJS] Body로 데이터 보낼 때 DTO로 보내지 않는 경우 주의하기

@Post('workshops/orderInfo')
@UserGuards(JwtUserAuthGuard)
async tryWorkshopOrderInfo(
 @Body() workshopDetailId: number,
 @CurrentUser() user: CurrentUserDto,
) {
  const result = awit this.mypageService.checkStatus(
    user.id,
    workshopDetailId
  );
  return result;
}

이 경우 프론트에서 axios로 통신하여 받은 값을 제대로 인식하지 못할 수 있다. 왜냐하면 데이터를 json 형태로 보내주는데 서버에서 파싱을 하지 못하기 때문이다.

서버에서 콘솔을 찍어본 결과 WorkshopInstanceDetail { id: 3, status: 'non_payment' } 라는 값으로 전달되는 것을 확인할 수 있었다.

body 안에 객체 형태로 전달되므로 body: { workshopDetailId: number }로 인자를 전달하면 무사히 전달할 수 있다.

보내는 데이터가 하나뿐이라 DTO를 사용하지 않고 바로 Body로 전달했는데, 값이 제대로 전달되지 않아 애먹었다. (^_ㅠ...)

반면 @Params()의 경우에는 값을 괄호 안에 넣어서 파싱해줘야 한다.


[NestJS] DTO 작성 시 useGlobalPipes > validationPipe whitelist: true 설정되어 있는 경우 ('propery ~ should not exist' 에러 발생)

아임포트로 결제 기능을 구현하는데 계속 Body 데이터를 보낼 때 property ~ should not exist 에러가 발생했다.

export class PaymentDto {
  workshop_id: number;

  imp_uid: string;

  merchant_uid: string;
}

DTO에 Body로 보낼 값들이 빠짐없이 선언되어 있었고, 데이터를 잘 전달하는데도 property ~ shuld not exist 에러가 발생해서 한참 삽질을 했다.

해결 방법

원인은 main.ts에 useGlobalPipes에 있었다.

    this.server.useGlobalPipes(
      new ValidationPipe({
        whitelist: true,
        forbidNonWhitelisted: true,
        transform: true,
      }),

전역으로 작동하는 useGlobalPipes에 데이터의 유효성을 검사하는 ValidationPipe가 설치되어 있었는데, 그 옵션들의 의미는 다음과 같다.

  • whiteList: 엔티티 데코레이터에 없는 프로퍼티 값은 무조건 거름
  • forbidNonWhitelisted: 엔티티 데코레이터에 없는 값 인입시 그 값에 대한 에러메세지 알려줌
  • transform: 컨트롤러가 값을 받을때 컨트롤러에 정의한 타입으로 형변환

forbidNonWhitelisted 옵션을 사용하면 whitelist 옵션이 true로 설정된 상태에서, 검사 대상으로 지정되지 않은 속성이 데이터 객체에 존재하는 경우, 유효성 검사를 실패시키고 예외를 발생시킨다.

따라서 유효성을 검사하는 데코레이터를 선언하지 않은 채로 DTO를 만들었기 때문에 에러를 발생시킨 것이다.

DTO 선언 시 데코레이터를 추가했더니 에러가 발생하지 않았다.

profile
Back-End Wep Developer. 꾸준함이 능력이다.

0개의 댓글