Back End/트러블슈팅

[트러블슈팅] Pageable 사용 시 Swagger 에서 쿼리파라미터 불일치 문제 원인 및 해결

DevPing9_ 2023. 3. 22. 20:09

 

일반적인 Pageable 을 인자로 받는 컨트롤러


보통 Pageable 을 사용한 RestController 는 아래와 같은 모양을 갖는다.

 

@GetMapping("/user/product")
fun findUserProducts(
    @ApiIgnore session : HttpSession,
    @PageableDefault(size = 24) pageable: Pageable
): ResponseEntity<CommonResponse<UserProductResponse>> {
    val userId = session.getUserId()
    val data = userProductService.findSliceByUserId(userId, pageable)
    return ResponseEntity.ok(CommonResponse(data = UserProductResponse.of(data)))
}

 

그리고 Pageable 을 인자로 받는 컨트롤러는 쿼리파라미터로 page, size, sort 를 가지게 되어 아래와 같이 API 를 호출하게 된다.

 

{domain}/user/product?page=2

 

Pageable 을 인자로 받는 컨트롤러의 Swagger


그런데 Swagger 문서는 아래와 같이 생성된다.

그리고 Swagger 문서의 쿼리파라미터인 pageNumber=25 로 호출하면 unknown query parameter 로 인식하고 아무런 에러 없이 page=0 으로 호출된다.

 

 

 

Swagger 와 불일치 원인


구현체인 PageRequest 가 Pageable 인터페이스를 상속하고 있기 때문이다.

Swagger 는 getter 를 보고 문서를 생성하고, 컨트롤러는 생성자를 보고 쿼리파라미터를 인식한다.

 

 

 

해결방법


구현체인 PageRequest 를 인식시키도록 하면 되겠네! 하고 쿼리파라미터의 자료형을 Pageable -> PageRequest 로 바꿨더니 에러가 났다 ㅎㅎ...

 

구글링해서 찾은 결과는 Swagger Config 에 설정을 추가하는 것이다.

 

SwaggerConfig

@Profile("local")
@Configuration
class SwaggerConfig {

    @Bean
    fun api(): Docket = Docket(DocumentationType.OAS_30)
        .directModelSubstitute(Pageable::class.java, SwaggerPageable::class.java) // <- Pageable 을 SwaggerPageable 로 대체 
        .globalRequestParameters(listOf(globalCsrfParameter()))
        .useDefaultResponseMessages(false)
        .servers(makeServer())
        .select()
        .apis(RequestHandlerSelectors.withMethodAnnotation(Operation::class.java))
        .paths(PathSelectors.any())
        .build()

    fun globalCsrfParameter(): RequestParameter = RequestParameterBuilder().name("X-CSRF-TOKEN")
        .`in`(ParameterType.HEADER)
        .required(false)
        .build()

    fun makeServer(): Server = Server("local", "http://localhost:8082", "local", listOf(), listOf())
}

 

SwaggerPageable

@ApiModel
data class SwaggerPageable(
    val page: Int,
    val size: Int,
    @ApiModelProperty("컬럼명,ASC||DESC (e.g. 'bid,asc')")
    val sort: String,
)

 

728x90