Bernhard
08/13/2026, 11:56 AMCLOVIS
08/13/2026, 12:19 PMBernhard
08/13/2026, 12:19 PMBernhard
08/13/2026, 12:20 PMBernhard
08/13/2026, 12:21 PMBernhard
08/13/2026, 12:21 PMJsonTypeInfo(use = DEDUCTION)CLOVIS
08/13/2026, 12:22 PMJsonObject and then use whatever code you want to convert it into the final objectBernhard
08/13/2026, 12:23 PMCLOVIS
08/13/2026, 12:23 PMCasey Brooks
08/13/2026, 1:06 PMclassDiscriminator lets you use a property other than type to distinguish between the types https://github.com/Kotlin/kotlinx.serialization/blob/master/docs/json.md#class-discriminator-for-polymorphismBen Woodworth
08/17/2026, 5:44 PMJuan Hurtado
08/24/2026, 6:08 AM@GhostSerialization(inferred = true) does field-presence polymorphism (like Jackson DEDUCTION). You can use it only on that sealed hierarchy — dual-annotate, put the Ghost converter before KotlinX so Ghost handles that DTO and everything else falls through — without replacing the rest of the stack, and those models tend to decode faster too.
github.com/juanchurtado1991/ghost-serializer
@Serializable // keep for KotlinX call sites
@GhostSerialization(inferred = true)
sealed class SmartEvent {
@Serializable
@GhostSerialization
data class Temperature(@GhostSignature val celsius: Double) : SmartEvent()
@Serializable
@GhostSerialization
data class Motion(@GhostSignature val sensorId: String, val zone: Int) : SmartEvent()
}
// { "celsius": 24.5 } → Temperature
// { "sensorId": "SN-01", "zone": 1 } → Motion
// Ktor — Ghost first, KotlinX fallback
install(ContentNegotiation) {
ghost()
json(Json { ignoreUnknownKeys = true })
}Bernhard
08/24/2026, 8:04 AM