Backend/Spring+Boot

swagger 사용시 패키지가 다른 동일 클래스를 구별하지 못하는 이슈

findmypiece 2023. 8. 30. 00:37
728x90

여러명의 개발자가 페어로 개발을 하다보면 클래스명은 동일하지만 패키지를 다르게 해서 생성하게 되는 경우가 있다.

중복 클래스가 아니라 엄연히 다른 클래스인데 명칭이 중복되는 경우도 있고 inner class 명이 서로 다른 클래스 하위에 중복으로 선언될 수도 있다.

 

swagger 에서는 Controller 에서 사용되는 클래스들을 Schema 로 분류해서 관리하는데 기본적으로 패키지를 포함해서 관리하지 않기 때문에 클래스명이 동일할 경우 이를 구분하지 못한다.

 

예를 들어 아래와 같이 2개의 VO 클래스와 Controller 메소드가 정의되어 있다고 가정해보자.

data class Vo1(
  val transferablePeriod: TransferablePeriod
) {
  data class TransferablePeriod(
      val endDate: LocalDateTime
  )
}

data class Vo2(
  val transferablePeriod: TransferablePeriod
) {
  data class TransferablePeriod(
      val startDate: LocalDateTime
      val endDate: LocalDateTime
  )
}

...

@PostMapping("test")
@Operation(
    summary = "테스트 Api"
)
fun test(
    @RequestBody
    vo1: Vo1
) {
  ...
}

 

TransferablePeriod 라는 inner class 가 각각 다르게 정의되어 있다. 우리가 정의한 Controller 메소드에서는 Vo1 을 request body 로 받고 있기 때문에 Vo1.TransferablePeriod 가 매핑될거라 기대하지만 이는 장담할 수 없다. Vo2.TransferablePeriod 가 매핑될 수도 있다.

 

이유는 위에서 말했듯이 swagger 에서는 Schema 를 관리할때 기본적으로 패키지를 포함하지 않기 때문에 실제로 TransferablePeriod는 2개 선언되었지만 1개 클래스만 랜덤으로 선택되어 관리되고 매핑도 그걸로 된다.

 

이를 해결하기 위한 방법들이 몇개 소개되어 있다

https://github.com/swagger-api/swagger-core/issues/2121#issuecomment-1260972235
https://stackoverflow.com/questions/65284116/swagger-2-0-how-to-solve-same-response-class-names-in-different-packages-issue

 

간단한 해결방법은 두번째 소개된 방식인데 application.yml 에 아래와 같은 설정값만 추가하면 된다.

springdoc:
  use-fqn: true

 

이렇게 할 경우 Schema 가 패키지를 포함해서 관리되기 때문에 큺래스명이 동일하더라도 정상적으로 구분해서 매핑된다.

728x90