I have an object
@Serializable
data class Manufacturer(
val uuid: String? = null,
val name: String,
val cars: List<CarModel> = emptyList()
)
That is used to convert a request body into an internal object. CarModel
is defined as follows:
@Serializable
data class CarModel(val uuid: String? = null, val carType: String, val name: String)
Now I can define a request body
{
"name": "Test Name",
}
And the request is successful, however when I add a list representing car models, the request fails with the error: Failed to convert request body to class
Here's an example request body
{
"name": "Manufacturer 1",
"cars": [
{
"car_type": "Sedan",
"name": "Car 1",
},
{
"car_type": "Sedan",
"name": "Car 2",
},
]
}
It seems like ktor is having trouble deserializing nested objects, which is why when I provide a list of cars, it fails, but I can't figure out how to work around this, when the CarModel
itself is serializable, so in theory, should be implicitly supported? I can successfully send list of strings, I just am unable to handle custom objects.
EDIT: Added Stack Trace
2024-12-03 09:40:24.588 [eventLoopGroupProxy-4-3] TRACE io.ktor.routing.Routing - Trace for [manufacturer]
/, segment:0 -> SUCCESS @ /
/ws, segment:0 -> FAILURE "Selector didn't match" @ /ws
/json, segment:0 -> FAILURE "Selector didn't match" @ /json
/manufacturers, segment:0 -> FAILURE "Selector didn't match" @ /manufacturers
/manufacturer, segment:1 -> SUCCESS @ /manufacturer
/manufacturer/(method:POST), segment:1 -> SUCCESS @ /manufacturer/(method:POST)
/tag, segment:0 -> FAILURE "Selector didn't match" @ /tag
Matched routes:
"" -> "manufacturer" -> "(method:POST)"
Route resolve result:
SUCCESS @ /manufacturer/(method:POST)
2024-12-03 09:40:24.650 [eventLoopGroupProxy-4-3] TRACE i.k.server.engine.DefaultTransform - No Default Transformations found for class io.ktor.utils.io.ByteBufferChannel and expected type TypeInfo(type=class com.carapp.models.Manufacturer, reifiedType=class com.carapp.models.Manufacturer, kotlinType=com.carapp.models.Manufacturer) for call /manufacturer
2024-12-03 09:40:24.689 [eventLoopGroupProxy-4-3] TRACE i.k.s.p.statuspages.StatusPages - Call /manufacturer failed with cause io.ktor.server.plugins.BadRequestException: Failed to convert request body to class com.carapp.models.Manufacturer
2024-12-03 09:40:24.714 [eventLoopGroupProxy-4-3] TRACE i.k.s.p.statuspages.StatusPages - Executing (io.ktor.server.application.ApplicationCall, kotlin.Throwable) -> kotlin.Unit for exception io.ktor.server.plugins.BadRequestException: Failed to convert request body to class com.carapp.models.Manufacturer for call /manufacturer
2024-12-03 09:40:24.715 [eventLoopGroupProxy-4-3] TRACE i.k.s.p.c.ContentNegotiation - Skipping because body is already converted.
As it turns out, the key I was using in the JSON when making the request to representCar.carType
was incorrect - I was sending along car_type
when I should have been sending carType
as the JSON key, so the correct JSON body is actually:
{
"name": "Manufacturer 1",
"cars": [
{
"carType": "Sedan",
"name": "Car 1",
},
{
"carType": "Sedan",
"name": "Car 2",
},
]
}