Node.js

[NestJS] Swagger 바디 타입 여러개 명시하기

임채성 2022. 10. 17. 16:00

헬스 기구 처리 로직 소개

바디로 여러개의 타입 중 하나를 선택해서 입력하는 로직을 구현하고 있었다.

우선, 운동 레퍼지토리는 이렇게 생겼다.

무산소, 유산소 타입의 합집합이다.

 

이걸 저장하는 방식은 2가지가 있다.

  1. 1개의 저장 컨트롤러에 2가지 타입의 DTO를 받는 것.


  2. 2개의 저장 컨트롤러를 만들어서 DTO와 1:1로 연결하여 저장하는 것

저는 관리 측면이 편하기 때문에 1번 방식을 이용하기로 했습니다.

 

여기서 발생한 문제는 스웨거에 어떻게 넣을 것인가..

  1. enum으로 넣으면 터집니다.
  2. 하나만 넣으면 문서화 작업의 의미가 사라집니다.
  3. 2개의 클래스를 타입으로 사용하면 에러가 납니다.

 

그래서 어떻게 구현했는데?

구현 방법이 있었습니다.

@POST('저장 경로')
@ApiOperation({
  summary: '루틴 메뉴얼을 생성합니다.',
})
@ApiExtraModels(
  RoutineCardioManualCreateRequest,
  RoutineWeightManualCreateRequest,
)
@ApiBody({
  description: '운동 종류에 따라 다른 데이터를 입력합니다.',
  schema: {
    oneOf: [
      {
        $ref: getSchemaPath(RoutineWeightManualCreateRequest),
      },
      {
        $ref: getSchemaPath(RoutineCardioManualCreateRequest),
      },
    ],
  },
	examples: {
    무산소: {
      value: {
        weight: 20,
        setNumber: 3,
        targetNumber: 15,
        order: 1,
      },
    },
    유산소: {
      value: {
        speed: 7,
        playMinute: 30,
        order: 1,
      },
    },
  },
})
@ApiOkResponse({
  type: RoutineManualProfileResponse,
})
async createRoutineManual(
	@Body()
  data: RoutineCardioManualCreateRequest | RoutineWeightManualCreateRequest,
): Promise<RoutineManualProfileResponse> {
  return this.routineManualService.createRoutineManual(data);
}

이런식으로 넣는다면 다음과 같은 결과를 얻을 수 있습니다.


 

추후에 수정해야하는 것

value를 직접적으로 입력하는 방식은 후에 DTO를 수정하였을 때 별도로 작업을 해주어야하는 방식입니다.

request DTO 프로퍼티를 가져오는 방식으로 리팩토링하여 데이터 유효성을 확인할 필요가 있습니다.

 

참고 레퍼런스

https://stackoverflow.com/questions/72232818/how-can-i-have-multiple-dtos-for-nestjs-request-body-swagger

 

How can I have multiple DTO's for NestJS Request Body/Swagger

so I have a route that can accept two different DTO's. I'm having difficulty getting these two DTO's to link/show up on swagger. I'm using the swagger plugin with NestJS. I know in raw swagger you ...

stackoverflow.com