I am in the process of converting from Moshi to kotlinx serialization with Ktor and when I try to make a request to get data I am getting this error
kotlinx.serialization.MissingFieldException: Field 'attachments' is required, but it was missing
which makes sense since this specific response does not contain this field
Response Json
{
"data": {
"id": "1299418846990921728",
"text": "This is a test"
}
}
BUT my Serialized class has the attachments
field as nullable (it is in the response only when it needs to be) so it should just ignore it I thought like it did with Moshi
@Serializable
data class ResponseData(
val id: Long
val attachments: Attachments?,
val author_id: String?,
val text: String
}
In my Ktor client setup I have it set to ignore unknown keys
private val _client: HttpClient = HttpClient(engine) {
install(JsonFeature) {
val json = Json {
this.isLenient = true
this.ignoreUnknownKeys = true
}
serializer = KotlinxSerializer(json)
}
}
Why is it still saying that the field is required even though its nullable?
In Kotlin, data serialization tools are available in a separate component, kotlinx.serialization. It consists of two main parts: the Gradle plugin – org.jetbrains.kotlin.plugin.serialization and the runtime libraries.
install (JsonFeature) { serializer = KotlinxSerializer ( json = kotlinx.serialization.json.Json { explicitNulls = false } ) } Specifies whether null values should be encoded for nullable properties and must be present in JSON object during decoding.
It consists of two main parts: the Gradle plugin – org.jetbrains.kotlin.plugin.serialization and the runtime libraries. kotlinx.serialization provides sets of libraries for all supported platforms – JVM, JavaScript, Native – and for various serialization formats – JSON, CBOR, protocol buffers, and others.
Serialization is the process of converting data used by an application to a format that can be transferred over a network or stored in a database or a file. In turn, deserialization is the opposite process of reading data from an external source and converting it into a runtime object.
I figured it out, apparently even though you mark something as nullable its still considered required.
For it to truly be optional you need to give it a default value so for example the data class would look like this with the nullables
@Serializable
data class ResponseData(
val id: Long
val attachments: Attachments? = null,
val author_id: String? = null,
val text: String
}
once you set the value the fields becomes optional and wont throw that exception
As of v1.3.0, you can configure the Json feature to treat absent fields as null, with explicitNulls = false
install(JsonFeature) {
serializer = KotlinxSerializer(
json = kotlinx.serialization.json.Json {
explicitNulls = false
}
)
}
The documentation for explicitNulls
:
Specifies whether null values should be encoded for nullable properties and must be present in JSON object during decoding. When this flag is disabled properties with null values without default are not encoded; during decoding, the absence of a field value is treated as null for nullable properties without a default value. true by default.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With