Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Kotlinx Serialization MissingFieldException

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?

like image 845
tyczj Avatar asked Nov 12 '20 02:11

tyczj


People also ask

What is data serialization in Kotlin?

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.

What is explicitnulls in kotlinx serializer?

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.

What are the parts of Kotlin?

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.

What is serialization and deserialization?

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.


Video Answer


2 Answers

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

like image 58
tyczj Avatar answered Sep 24 '22 06:09

tyczj


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.

like image 28
Tim Malseed Avatar answered Sep 22 '22 06:09

Tim Malseed