Model Polymorphic JSON with Kotlin Sealed Classes
Learn how to use Kotlin sealed classes to represent polymorphic JSON structures where the shape varies by type. Covers discriminator fields and exhaustive pattern matching.
Detailed Explanation
Polymorphic JSON with Sealed Classes
When a JSON field can contain objects of different shapes depending on a discriminator (like "type"), Kotlin sealed classes provide type-safe representation with exhaustive pattern matching.
Example JSON
{
"type": "text",
"content": "Hello, world!"
}
{
"type": "image",
"url": "https://example.com/photo.jpg",
"width": 800,
"height": 600
}
Generated Kotlin
@Serializable
sealed class Message {
abstract val type: String
@Serializable
@SerialName("text")
data class Text(
override val type: String = "text",
val content: String
) : Message()
@Serializable
@SerialName("image")
data class Image(
override val type: String = "image",
val url: String,
val width: Int,
val height: Int
) : Message()
}
Exhaustive When Expression
fun render(message: Message) = when (message) {
is Message.Text -> renderText(message.content)
is Message.Image -> renderImage(message.url, message.width, message.height)
// Compiler error if a subtype is not handled
}
kotlinx.serialization Polymorphism
val module = SerializersModule {
polymorphic(Message::class) {
subclass(Message.Text::class)
subclass(Message.Image::class)
}
}
val json = Json {
serializersModule = module
classDiscriminator = "type"
}
When to Use Sealed Classes vs Enum Classes
| Feature | Enum | Sealed Class |
|---|---|---|
| Fixed set of values | Yes | Yes |
| Each variant holds different data | No | Yes |
| Pattern matching | Yes | Yes |
| Serializable out of the box | Yes | Needs setup |
Use enum when variants are just labels. Use sealed class when each variant has a different structure.
Sealed Interface (Kotlin 1.5+)
sealed interface Event {
data class Click(val x: Int, val y: Int) : Event
data class KeyPress(val key: String) : Event
data object Logout : Event
}
Sealed interfaces allow a class to implement multiple sealed hierarchies, offering more flexibility than sealed classes.
Use Case
Chat applications, notification systems, and event-driven architectures receive JSON payloads with varying shapes. Sealed classes ensure every variant is handled at compile time, eliminating missed-case bugs in Android UI rendering and server event processing.
Try It — JSON to Kotlin
Related Topics
Map JSON String Values to Kotlin Enum Classes
Advanced Patterns
Model a REST API Response in Kotlin Data Classes
Real-World Patterns
Convert Nested JSON Objects to Kotlin Data Classes
Basic Data Classes
Kotlin Serialization Annotations for JSON Mapping
Serialization
Use Kotlin Generics for Reusable JSON Response Wrappers
Advanced Patterns