0
# Kotlinx Serialization
1
2
Kotlinx Serialization-based JSON implementation for Ktor HTTP clients. Provides compile-time safe serialization with advanced features like polymorphism, custom serializers, and contextual serialization.
3
4
## Capabilities
5
6
### KotlinxSerializer Class
7
8
JsonSerializer implementation using kotlinx.serialization library for JSON processing.
9
10
```kotlin { .api }
11
/**
12
* A JsonSerializer implemented for kotlinx Serializable classes.
13
*/
14
@Deprecated("Please use ContentNegotiation plugin and its converters")
15
class KotlinxSerializer(private val json: Json = DefaultJson) : JsonSerializer {
16
/**
17
* Convert data object to OutgoingContent using kotlinx.serialization.
18
*/
19
override fun write(data: Any, contentType: ContentType): OutgoingContent
20
21
/**
22
* Read content from response using kotlinx.serialization deserialization.
23
*/
24
override fun read(type: TypeInfo, body: Input): Any
25
26
/**
27
* Internal method for content serialization.
28
*/
29
internal fun writeContent(data: Any): String
30
31
companion object {
32
/**
33
* Default Json configuration for KotlinxSerializer.
34
*/
35
val DefaultJson: Json
36
}
37
}
38
```
39
40
### Default Json Configuration
41
42
Preconfigured Json instance with sensible defaults for HTTP client usage.
43
44
```kotlin { .api }
45
val DefaultJson: Json = Json {
46
isLenient = false
47
ignoreUnknownKeys = false
48
allowSpecialFloatingPointValues = true
49
useArrayPolymorphism = false
50
}
51
```
52
53
## Service Registration
54
55
The KotlinxSerializer is automatically discoverable on JVM through the ServiceLoader mechanism:
56
57
**META-INF/services/io.ktor.client.plugins.json.JsonSerializer**
58
```
59
io.ktor.client.plugins.kotlinx.serializer.KotlinxSerializer
60
```
61
62
## Dependencies
63
64
To use KotlinxSerializer, add the kotlinx.serialization dependency:
65
66
**Gradle**
67
```kotlin
68
implementation("io.ktor:ktor-client-serialization:2.3.13")
69
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.5.1")
70
```
71
72
**Maven**
73
```xml
74
<dependency>
75
<groupId>io.ktor</groupId>
76
<artifactId>ktor-client-serialization-jvm</artifactId>
77
<version>2.3.13</version>
78
</dependency>
79
```
80
81
## Usage Examples
82
83
### Basic Usage
84
85
```kotlin
86
import io.ktor.client.*
87
import io.ktor.client.plugins.json.*
88
import io.ktor.client.plugins.kotlinx.serializer.*
89
import kotlinx.serialization.*
90
91
val client = HttpClient {
92
install(JsonPlugin) {
93
serializer = KotlinxSerializer()
94
}
95
}
96
```
97
98
### Custom Json Configuration
99
100
```kotlin
101
import kotlinx.serialization.json.*
102
103
val client = HttpClient {
104
install(JsonPlugin) {
105
serializer = KotlinxSerializer(Json {
106
prettyPrint = true
107
isLenient = true
108
ignoreUnknownKeys = true
109
coerceInputValues = true
110
useAlternativeNames = false
111
namingStrategy = JsonNamingStrategy.SnakeCase
112
explicitNulls = false
113
})
114
}
115
}
116
```
117
118
### Serializable Data Classes
119
120
```kotlin
121
import kotlinx.serialization.*
122
123
@Serializable
124
data class User(
125
val id: Long,
126
val name: String,
127
val email: String,
128
@SerialName("created_at")
129
val createdAt: String
130
)
131
132
// POST request - automatic serialization
133
val response = client.post("https://api.example.com/users") {
134
contentType(ContentType.Application.Json)
135
setBody(User(0, "Alice", "alice@example.com", "2023-01-01"))
136
}
137
138
// GET request - automatic deserialization
139
val user: User = client.get("https://api.example.com/users/1").body()
140
```
141
142
### Polymorphic Serialization
143
144
```kotlin
145
@Serializable
146
sealed class Animal {
147
abstract val name: String
148
}
149
150
@Serializable
151
@SerialName("dog")
152
data class Dog(
153
override val name: String,
154
val breed: String
155
) : Animal()
156
157
@Serializable
158
@SerialName("cat")
159
data class Cat(
160
override val name: String,
161
val color: String
162
) : Animal()
163
164
// Usage
165
val animals: List<Animal> = listOf(
166
Dog("Buddy", "Golden Retriever"),
167
Cat("Whiskers", "Orange")
168
)
169
170
val response = client.post("https://api.example.com/animals") {
171
contentType(ContentType.Application.Json)
172
setBody(animals)
173
}
174
```
175
176
### Custom Serializers
177
178
```kotlin
179
import kotlinx.serialization.*
180
import kotlinx.serialization.descriptors.*
181
import kotlinx.serialization.encoding.*
182
import java.time.LocalDateTime
183
import java.time.format.DateTimeFormatter
184
185
@Serializer(forClass = LocalDateTime::class)
186
object LocalDateTimeSerializer : KSerializer<LocalDateTime> {
187
private val formatter = DateTimeFormatter.ISO_LOCAL_DATE_TIME
188
189
override val descriptor: SerialDescriptor =
190
PrimitiveSerialDescriptor("LocalDateTime", PrimitiveKind.STRING)
191
192
override fun serialize(encoder: Encoder, value: LocalDateTime) {
193
encoder.encodeString(value.format(formatter))
194
}
195
196
override fun deserialize(decoder: Decoder): LocalDateTime {
197
return LocalDateTime.parse(decoder.decodeString(), formatter)
198
}
199
}
200
201
@Serializable
202
data class Event(
203
val id: Long,
204
val name: String,
205
@Serializable(with = LocalDateTimeSerializer::class)
206
val timestamp: LocalDateTime
207
)
208
```
209
210
### Contextual Serialization
211
212
```kotlin
213
// Define contextual serializer
214
val module = SerializersModule {
215
contextual(LocalDateTime::class, LocalDateTimeSerializer)
216
}
217
218
val client = HttpClient {
219
install(JsonPlugin) {
220
serializer = KotlinxSerializer(Json {
221
serializersModule = module
222
})
223
}
224
}
225
226
@Serializable
227
data class Event(
228
val id: Long,
229
val name: String,
230
@Contextual
231
val timestamp: LocalDateTime
232
)
233
```
234
235
### Collection Handling
236
237
```kotlin
238
// List serialization
239
@Serializable
240
data class UserList(val users: List<User>)
241
242
// Map serialization
243
@Serializable
244
data class UserMap(val users: Map<String, User>)
245
246
// Direct collection serialization
247
val users: List<User> = client.get("https://api.example.com/users").body()
248
val userMap: Map<String, User> = client.get("https://api.example.com/users/map").body()
249
```
250
251
### Error Handling
252
253
```kotlin
254
import kotlinx.serialization.*
255
256
try {
257
val user: User = client.get("https://api.example.com/users/1").body()
258
} catch (e: SerializationException) {
259
// Serialization/deserialization error
260
logger.error("JSON serialization error", e)
261
} catch (e: MissingFieldException) {
262
// Required field missing
263
logger.error("Missing required field", e)
264
} catch (e: UnknownKeyException) {
265
// Unknown key in JSON (when ignoreUnknownKeys = false)
266
logger.error("Unknown JSON key", e)
267
}
268
```
269
270
### Advanced Configuration
271
272
```kotlin
273
val client = HttpClient {
274
install(JsonPlugin) {
275
serializer = KotlinxSerializer(Json {
276
// Parsing options
277
isLenient = true // Allow lenient parsing
278
ignoreUnknownKeys = true // Ignore unknown JSON keys
279
coerceInputValues = true // Coerce invalid values to defaults
280
281
// Output options
282
prettyPrint = true // Pretty print JSON
283
prettyPrintIndent = " " // Custom indent
284
285
// Null handling
286
explicitNulls = false // Don't encode null values
287
288
// Naming strategy
289
namingStrategy = JsonNamingStrategy.SnakeCase
290
291
// Special values
292
allowSpecialFloatingPointValues = true // Allow NaN, Infinity
293
allowStructuredMapKeys = true // Allow complex map keys
294
295
// Polymorphism
296
useArrayPolymorphism = false // Use object polymorphism
297
298
// Custom serializers module
299
serializersModule = SerializersModule {
300
contextual(LocalDateTime::class, LocalDateTimeSerializer)
301
polymorphic(Animal::class) {
302
subclass(Dog::class)
303
subclass(Cat::class)
304
}
305
}
306
})
307
}
308
}
309
```
310
311
## Json Configuration Options
312
313
The KotlinxSerializer supports extensive Json configuration:
314
315
### Parsing Options
316
- `isLenient`: Allow lenient JSON parsing
317
- `ignoreUnknownKeys`: Ignore unknown properties
318
- `coerceInputValues`: Coerce invalid input to defaults
319
- `allowStructuredMapKeys`: Allow non-primitive map keys
320
- `allowSpecialFloatingPointValues`: Allow NaN and Infinity
321
322
### Output Options
323
- `prettyPrint`: Enable pretty printing
324
- `prettyPrintIndent`: Custom indentation string
325
- `explicitNulls`: Control null value encoding
326
327
### Advanced Features
328
- `serializersModule`: Custom serializers and polymorphism
329
- `namingStrategy`: Field naming strategy
330
- `useArrayPolymorphism`: Polymorphism format choice
331
332
## Performance Considerations
333
334
- Json instances are thread-safe and should be reused
335
- Contextual serializers are resolved at runtime
336
- Use `@Serializable` annotation for compile-time code generation
337
- Consider using sealed classes for polymorphic hierarchies
338
- Custom serializers should be lightweight and stateless