특정 컨트롤러에서 다중 DTO를 받아 Service 로직에서 맞는 DTO에 따라 동작하게 설계하였는데

## controller

@Post('create')
async create(@Body() body: CreatePaymentPortoneDto | CreatePaymentPaypalDto) {
  return await this.paymentService.create(body);
}

내 머리속에 있는 동작대로라면, 맞는 DTO에 body가 매핑되는걸 예상했지만 어림도 없었다.

저 방식대로 설계를 하게되면 서비스 로직에서의 동작 자체는 문제가 없는데, body데이터의 validate가 정상적으로 체크되지 않고 그냥 넘겨버린다….

이유는 body의 타입 선언을 멀티로 하니 타입이 날아가버리는 것 같았다..

그래서 해결방법은, 해당 DTO들의 부모 클래스의 공통 사항을 가지고 체크를 했다.

저장되는 테이블은 동일하지만 결제 타입이 어떤건지 확인하기 위한 컬럼이 있어서 해당 컬럼을 가지고 type cast 를 해주기로 했다.

## controller

@Post('create')
  async create(@Body() body: CreatePaymentPortoneDto | CreatePaymentPaypalDto) {
    switch (body.payment_type) {
      case PaymentType.portone: {
        body = Object.setPrototypeOf(body, CreatePaymentPortoneDto.prototype);
        await validate(body).then(async (errors) => {
          if (errors.length > 0) {
            throw new HttpException('Bad Request', HttpStatus.BAD_REQUEST);
          } else {
            return await this.paymentService.create(body);
          }
        });
        break;
      }
      case PaymentType.paypal: {
        body = Object.setPrototypeOf(body, CreatePaymentPaypalDto.prototype);
        await validate(body).then(async (errors) => {
          if (errors.length > 0) {
            throw new HttpException('Bad Request', HttpStatus.BAD_REQUEST);
          } else {
            return await this.paymentService.create(body);
          }
        });
        break;
      }
      default: {
        throw new HttpException('Bad Request', HttpStatus.BAD_REQUEST);
      }
    }
  }

위의 방식을 통해 body에 넘어오는 DTO는 명시만 해주고,

하위에서 body의 결제 타입을 체크하고, 해당 타입에 맞게 캐스팅 해주었다.

물론.. 결제 타입에 맞는 DTO와 함수와 endpoint 를 추가해주면 간단히 해결할 수 있는 문제였고, endpoint와 dto를 추가해서 처리하는 방식이 좋은 방향성일지라도, 하나의 endpoint와 같은 서비스 로직 함수로 연결되어야 할 때 해결방안을 찾고싶어서 위와같이 처리해보았다.