0
# Moshi Kotlin
1
2
Moshi Kotlin provides Kotlin-specific support for the Moshi JSON library through reflection-based JSON adapters. It enables seamless serialization and deserialization of Kotlin data classes with proper support for Kotlin language features like non-nullable types, default parameter values, and value classes.
3
4
## Package Information
5
6
- **Package Name**: moshi-kotlin
7
- **Package Type**: maven
8
- **Group ID**: com.squareup.moshi
9
- **Artifact ID**: moshi-kotlin
10
- **Language**: Kotlin
11
- **Installation**:
12
- Gradle: `implementation "com.squareup.moshi:moshi-kotlin:1.15.2"`
13
- Maven: `<dependency><groupId>com.squareup.moshi</groupId><artifactId>moshi-kotlin</artifactId><version>1.15.2</version></dependency>`
14
15
## Core Imports
16
17
```kotlin
18
import com.squareup.moshi.kotlin.reflect.KotlinJsonAdapterFactory
19
import com.squareup.moshi.Moshi
20
import com.squareup.moshi.JsonAdapter
21
```
22
23
## Basic Usage
24
25
```kotlin
26
import com.squareup.moshi.kotlin.reflect.KotlinJsonAdapterFactory
27
import com.squareup.moshi.Moshi
28
29
// Create Moshi instance with Kotlin support
30
val moshi = Moshi.Builder()
31
.add(KotlinJsonAdapterFactory())
32
.build()
33
34
// Define a Kotlin data class
35
data class User(
36
val name: String,
37
val age: Int,
38
val isActive: Boolean = true // Default parameter value
39
)
40
41
// Create adapter for the data class
42
val adapter: JsonAdapter<User> = moshi.adapter(User::class.java)
43
44
// Serialize to JSON
45
val user = User("Alice", 25)
46
val json: String = adapter.toJson(user)
47
// Result: {"name":"Alice","age":25,"isActive":true}
48
49
// Deserialize from JSON
50
val userFromJson: User? = adapter.fromJson(json)
51
```
52
53
## Capabilities
54
55
### Kotlin JSON Adapter Factory
56
57
The primary API that enables Kotlin-specific JSON serialization and deserialization for Moshi.
58
59
```kotlin { .api }
60
class KotlinJsonAdapterFactory : JsonAdapter.Factory {
61
override fun create(
62
type: Type,
63
annotations: MutableSet<out Annotation>,
64
moshi: Moshi
65
): JsonAdapter<*>?
66
}
67
```
68
69
**Parameters:**
70
- `type: Type` - The type for which to create a JSON adapter
71
- `annotations: MutableSet<out Annotation>` - Annotations present on the field or method
72
- `moshi: Moshi` - The Moshi instance to use for creating nested adapters
73
74
**Returns:**
75
- `JsonAdapter<*>?` - A JSON adapter for the given type wrapped with `nullSafe()`, or null if this factory cannot create one for the specified type
76
77
**Key Features:**
78
- **Kotlin Data Classes**: Automatically handles data classes with primary constructors
79
- **Nullable Types**: Respects Kotlin's nullable and non-nullable type system
80
- **Default Parameters**: Supports constructor parameters with default values
81
- **Property Binding**: Handles both mutable (`var`) and immutable (`val`) properties
82
- **Annotation Support**: Works with `@Json` annotations for custom field names
83
- **Value Classes**: Supports Kotlin value classes with proper type resolution
84
- **Generated Adapter Precedence**: Automatically prefers generated adapters (created with `@JsonClass(generateAdapter = true)`) when available, falls back to reflection-based adapters
85
- **Null Safety**: All returned adapters are automatically wrapped with `nullSafe()` for proper null handling
86
87
**Supported Class Types:**
88
- Data classes
89
- Regular classes with primary constructors
90
- Classes with both constructor parameters and additional properties
91
- Classes with optional/default constructor parameters
92
93
**Unsupported Class Types:**
94
- Interfaces
95
- Enums (use standard Moshi enum support)
96
- Abstract classes
97
- Inner classes
98
- Local classes
99
- Object declarations
100
- Sealed classes (requires custom adapters)
101
102
**Usage Example:**
103
104
```kotlin
105
// Basic data class
106
data class Person(val name: String, val age: Int)
107
108
// Data class with default values
109
data class Account(
110
val id: String,
111
val balance: Double = 0.0,
112
val isActive: Boolean = true
113
)
114
115
// Data class with @Json annotation
116
data class ApiResponse(
117
@Json(name = "user_id") val userId: String,
118
@Json(name = "full_name") val fullName: String
119
)
120
121
// Using the factory
122
val moshi = Moshi.Builder()
123
.add(KotlinJsonAdapterFactory())
124
.build()
125
126
val personAdapter = moshi.adapter(Person::class.java)
127
val accountAdapter = moshi.adapter(Account::class.java)
128
val responseAdapter = moshi.adapter(ApiResponse::class.java)
129
```
130
131
### Deprecated API (Compatibility)
132
133
For backward compatibility, there's a deprecated factory in the original package:
134
135
```kotlin { .api }
136
@Deprecated(
137
message = "this moved to avoid a package name conflict in the Java Platform Module System.",
138
replaceWith = ReplaceWith("com.squareup.moshi.kotlin.reflect.KotlinJsonAdapterFactory")
139
)
140
class KotlinJsonAdapterFactory : JsonAdapter.Factory
141
```
142
143
**Location**: `com.squareup.moshi.KotlinJsonAdapterFactory`
144
**Status**: Deprecated - use `com.squareup.moshi.kotlin.reflect.KotlinJsonAdapterFactory` instead
145
146
## Error Handling
147
148
The KotlinJsonAdapterFactory and generated adapters can throw several types of exceptions:
149
150
**JsonDataException**: Thrown when JSON data doesn't match expected Kotlin types
151
- Multiple values for the same property: "Multiple values for '${propertyName}' at ${reader.path}"
152
- Null values for non-nullable properties: Wrapped with `unexpectedNull()` utility
153
- Missing values for required constructor parameters: Wrapped with `missingProperty()` utility
154
155
**IllegalArgumentException**: Thrown for unsupported class types (via `require()` statements in the factory)
156
- Local classes: "Cannot serialize local class or object expression ${className}"
157
- Inner classes: "Cannot serialize inner class ${className}"
158
- Abstract classes: "Cannot serialize abstract class ${className}"
159
- Object declarations: "Cannot serialize object declaration ${className}"
160
- Sealed classes: "Cannot reflectively serialize sealed class ${className}. Please register an adapter."
161
162
**Usage Example:**
163
164
```kotlin
165
try {
166
val user = adapter.fromJson("""{"name":null,"age":25}""")
167
} catch (e: JsonDataException) {
168
// Handle null value for non-nullable property
169
println("JSON data error: ${e.message}")
170
}
171
```
172
173
## Advanced Usage
174
175
### Custom Field Names with @Json
176
177
```kotlin
178
import com.squareup.moshi.Json
179
180
data class User(
181
@Json(name = "full_name") val fullName: String,
182
@Json(name = "user_age") val age: Int
183
)
184
```
185
186
### Transient Fields
187
188
```kotlin
189
data class User(
190
val name: String,
191
val age: Int,
192
@Transient val tempData: String = "default" // Excluded from JSON
193
)
194
```
195
196
### Mixed Constructor and Property Binding
197
198
```kotlin
199
data class User(
200
val name: String, // Constructor parameter
201
val age: Int // Constructor parameter
202
) {
203
var lastLogin: Long = 0 // Additional property, not in constructor
204
}
205
```
206
207
### Integration with Moshi Adapters
208
209
```kotlin
210
val moshi = Moshi.Builder()
211
.add(Date::class.java, Rfc3339DateJsonAdapter()) // Custom adapters first
212
.addLast(KotlinJsonAdapterFactory()) // Use addLast() for general-purpose adapters
213
.build()
214
```
215
216
**Note:** Use `addLast()` when registering KotlinJsonAdapterFactory to ensure custom adapters take precedence over the reflection-based factory.
217
218
## Dependencies
219
220
This package has the following dependencies:
221
222
**Required Dependencies:**
223
- `com.squareup.moshi:moshi` - Core Moshi library (automatically included as API dependency)
224
- `org.jetbrains.kotlin:kotlin-reflect` - Kotlin reflection library (automatically included as API dependency)
225
226
**Runtime Requirements:**
227
- Kotlin Standard Library (`kotlin-stdlib`) must be present on the classpath during compilation for proper metadata annotations
228
- Minimum supported versions align with the core Moshi library requirements
229
230
**Notes:**
231
- The `kotlin-reflect` dependency adds approximately 2.5 MiB to your application
232
- For applications where this size is prohibitive, consider using `moshi-kotlin-codegen` instead for compile-time generation
233
- When both reflection and codegen adapters are present, generated adapters take precedence
234
235
## Types
236
237
All types are provided by the Moshi core library. The KotlinJsonAdapterFactory uses reflection to work with Kotlin's type system and doesn't define additional types beyond the factory class itself.