0
# JSON Serializer Interface
1
2
Abstract interface defining the contract for JSON serialization and deserialization in Ktor HTTP clients. Implementations provide specific backends like Gson or Kotlinx Serialization.
3
4
## Capabilities
5
6
### JsonSerializer Interface
7
8
Core interface that all JSON serializers must implement to provide serialization and deserialization functionality.
9
10
```kotlin { .api }
11
/**
12
* Client json serializer.
13
*/
14
@Deprecated("Please use ContentNegotiation plugin and its converters")
15
interface JsonSerializer {
16
/**
17
* Convert data object to OutgoingContent.
18
*/
19
fun write(data: Any, contentType: ContentType): OutgoingContent
20
21
/**
22
* Convert data object to OutgoingContent using default JSON content type.
23
*/
24
fun write(data: Any): OutgoingContent
25
26
/**
27
* Read content from response using information specified in type.
28
*/
29
fun read(type: TypeInfo, body: Input): Any
30
}
31
```
32
33
### Platform Default Serializer
34
35
Factory function for obtaining platform-specific default JSON serializer implementations.
36
37
```kotlin { .api }
38
/**
39
* Platform default serializer.
40
* Uses service loader on JVM.
41
* Consider adding one of the following dependencies:
42
* - ktor-client-gson
43
* - ktor-client-json
44
*/
45
expect fun defaultSerializer(): JsonSerializer
46
```
47
48
### Content Type Matcher
49
50
Interface for matching JSON content types, including variants with +json suffix.
51
52
```kotlin { .api }
53
interface ContentTypeMatcher {
54
fun contains(contentType: ContentType): Boolean
55
}
56
57
internal class JsonContentTypeMatcher : ContentTypeMatcher {
58
override fun contains(contentType: ContentType): Boolean
59
}
60
```
61
62
## Platform-Specific Implementations
63
64
### JVM Implementation
65
66
On JVM, the default serializer uses Java's ServiceLoader mechanism to discover available JsonSerializer implementations.
67
68
```kotlin { .api }
69
// JVM-specific implementation
70
actual fun defaultSerializer(): JsonSerializer {
71
val serializers = ServiceLoader.load(JsonSerializer::class.java).toList()
72
73
if (serializers.isEmpty()) {
74
error("""Fail to find serializer. Consider adding one of:
75
- ktor-client-gson
76
- ktor-client-json
77
- ktor-client-serialization""")
78
}
79
80
return serializers.maxByOrNull { it::javaClass.name }!!
81
}
82
```
83
84
### Service Provider Configuration
85
86
Serializer implementations register themselves via Java's ServiceLoader mechanism:
87
88
**META-INF/services/io.ktor.client.plugins.json.JsonSerializer**
89
```
90
io.ktor.client.plugins.gson.GsonSerializer
91
```
92
93
## Usage Examples
94
95
### Implementing Custom Serializer
96
97
```kotlin
98
import io.ktor.client.plugins.json.*
99
import io.ktor.http.*
100
import io.ktor.http.content.*
101
import io.ktor.util.reflect.*
102
import io.ktor.utils.io.core.*
103
104
class MyCustomSerializer : JsonSerializer {
105
override fun write(data: Any, contentType: ContentType): OutgoingContent {
106
val jsonString = mySerializationLibrary.toJson(data)
107
return TextContent(jsonString, contentType)
108
}
109
110
override fun write(data: Any): OutgoingContent {
111
return write(data, ContentType.Application.Json)
112
}
113
114
override fun read(type: TypeInfo, body: Input): Any {
115
val jsonString = body.readText()
116
return mySerializationLibrary.fromJson(jsonString, type.reifiedType)
117
}
118
}
119
```
120
121
### Using Default Serializer
122
123
```kotlin
124
val client = HttpClient {
125
install(JsonPlugin) {
126
// Uses platform default - discovered via ServiceLoader on JVM
127
serializer = defaultSerializer()
128
}
129
}
130
```
131
132
### Content Type Matching
133
134
```kotlin
135
// Built-in JSON content type matcher
136
val matcher = JsonContentTypeMatcher()
137
138
// Matches standard JSON
139
matcher.contains(ContentType.Application.Json) // true
140
141
// Matches JSON variants
142
matcher.contains(ContentType.parse("application/hal+json")) // true
143
matcher.contains(ContentType.parse("application/vnd.api+json")) // true
144
145
// Doesn't match non-JSON types
146
matcher.contains(ContentType.Text.Plain) // false
147
```
148
149
### Error Handling
150
151
```kotlin
152
try {
153
val data = serializer.read(typeInfo, inputStream)
154
} catch (e: Exception) {
155
// Handle serialization errors
156
logger.error("Failed to deserialize JSON", e)
157
}
158
```
159
160
## Implementation Requirements
161
162
When implementing JsonSerializer:
163
164
1. **Thread Safety**: Implementations should be thread-safe as they may be used concurrently
165
2. **Error Handling**: Should throw descriptive exceptions for malformed JSON or type mismatches
166
3. **Content Type**: The `write` method should respect the provided ContentType parameter
167
4. **Type Information**: The `read` method must use TypeInfo to deserialize to the correct type
168
5. **Resource Management**: Properly handle Input streams and close resources when needed