Backend/Ktor

[Ktor] 쿼리파라미터 직렬화 유틸 만들기

mopil 2023. 7. 10. 14:55
반응형

Ktor에는 스프링과 다르게 GET요청으로 넘어오는 쿼리 파라미터를 바로 객체로 직렬화해서 받는 기능을 제공하지 않는다.

 

fun Route.productRouter() {
    val productService: ProductService by inject()

    get(Uris.Product.GET_ALL_PRODUCTS) {
        val params = call.parameters["name"]
        call.respond(productService.getAllProducts(params))
    }
}

이런식으로 call.parameters에서 하나하나 꺼내서 작업해야한다.

검색쿼리 처럼 쿼리 파라미터가 많이 넘어오는 경우는 객체로 바로 직렬화해주면 편할 것 같아서 유틸 함수를 만들어봤다.

 

object RequestUtils {
    val mapper = jacksonObjectMapper()

    inline fun <reified T : Any> Parameters.toClass(): T {
        val map = entries().associate { it.key to (it.value.getOrNull(0) ?: throw IllegalArgumentException("Missing value for key ${it.key}")) }
        return mapper.convertValue(map, T::class.java)
    }

    inline fun <reified T : Any> ApplicationCall.getQueryParams(): T {
        return this.request.queryParameters.toClass()
    }
}

 

사용은 다음과 같이하면 된다.

 

fun Route.productRouter() {
    val productService: ProductService by inject()

    get(Uris.Product.GET_ALL_PRODUCTS) {
        val params = call.getQueryParams<GetProductRequest>() // receive와 동일하게 객체로 바로 받기
        call.respond(productService.getAllProducts(params))
    }
}

 

data class GetProductRequest(
    val name: String? = null,
    val price: Int? = null,
    val priceCondition: ProductPriceCondition? = null,
    val category: ProductCategory? = null,
    val offset: Long,
    val limit: Int
)

 

DTO에 잘 매핑된다.

 

반응형