Kotlin Serialization Annotations for JSON Mapping
Master kotlinx.serialization annotations like @Serializable, @SerialName, @Transient, and @EncodeDefault to control how Kotlin data classes map to JSON fields.
Detailed Explanation
kotlinx.serialization Annotations
Kotlin's official serialization library uses annotations to control how data classes are encoded to and decoded from JSON. Understanding these annotations is essential for precise JSON mapping.
Core Annotations
@Serializable
data class User(
@SerialName("user_id")
val userId: Int,
val name: String,
@Transient
val cachedHash: Int = 0,
@EncodeDefault
val role: String = "viewer",
@Required
val email: String
)
Annotation Reference
| Annotation | Purpose |
|---|---|
@Serializable |
Marks class for serialization; generates serializer |
@SerialName("key") |
Maps a property to a different JSON key |
@Transient |
Excludes property from serialization entirely |
@EncodeDefault |
Includes property in output even when it matches the default |
@Required |
Makes field mandatory during deserialization (no default) |
@SerialName for Key Mapping
Most JSON APIs use snake_case while Kotlin uses camelCase:
@Serializable
data class Event(
@SerialName("event_id") val eventId: String,
@SerialName("created_at") val createdAt: String,
@SerialName("is_public") val isPublic: Boolean
)
@Transient for Internal Fields
@Serializable
data class CachedUser(
val id: Int,
val name: String,
@Transient
val fetchedAt: Long = System.currentTimeMillis()
)
The fetchedAt field exists in the Kotlin object but never appears in JSON output and is never read from JSON input. It must have a default value.
@EncodeDefault Modes
@Serializable
data class Settings(
@EncodeDefault(EncodeDefault.Mode.ALWAYS)
val theme: String = "light",
@EncodeDefault(EncodeDefault.Mode.NEVER)
val internal: String = "default"
)
ALWAYS-- include in JSON even when equal to defaultNEVER-- omit from JSON when equal to default (this is the global default behavior)
Combining Annotations
@Serializable
data class ApiConfig(
@SerialName("base_url")
@Required
val baseUrl: String,
@SerialName("retry_count")
@EncodeDefault
val retryCount: Int = 3
)
These annotations give you full control over the JSON-to-Kotlin mapping without modifying the JSON source.
Use Case
When integrating with third-party APIs that use snake_case naming, @SerialName annotations let your Kotlin code follow camelCase conventions while correctly mapping to the API's field names. @Transient is essential for computed or cached fields that should not leak into network payloads.
Try It — JSON to Kotlin
Related Topics
Configure JSON Naming Strategy in Kotlin Serialization
Serialization
Convert Simple JSON to a Kotlin Data Class
Basic Data Classes
Use Default Values in Kotlin Data Classes for Missing JSON Fields
Serialization
Map JSON String Values to Kotlin Enum Classes
Advanced Patterns
Model Polymorphic JSON with Kotlin Sealed Classes
Advanced Patterns