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