Search code examples
jsonkotlinserializationkotlinx.serialization

How to serialize Kotlin data-class with default values into JSON using kotlinx.serialization?


There is an example of a class with a default value:

@Serializable
data class TestClass(
    val obligatory: String,
    val optional: Int = 0
)

It can be correctly deserialize from jsons like: { "obligatory":"text", "optional":1 } and { "obligatory":"text" }.
At the same time, the result of its serialization has to contain the attribute "optional".

As a result of serialization:

Json.encodeToString(TestClass("text"))

I expect { "obligatory":"text", "optional":0 }, however now I have { "obligatory":"text" }.

How should I change my code to achieve the expected result?


Solution

  • By default, Kotlinx Serialization doesn't encode default values. I guess it assumes you're using the same data model on the other side.

    You can force serializing default values when you configure your serializer:

    val json = Json { encodeDefaults = true }
    
    json.encodeToString(TestClass("text"))
    

    Since version 1.3.0, it is now also possible to change this behaviour only for specific properties using the @EncodeDefault annotation (independently of the format's config). So if you wanted this only for this specific property, you could write (and keep the default format config):

    @Serializable
    data class TestClass(
        val obligatory: String,
        @EncodeDefault
        val optional: Int = 0,
    )
    

    Conversely, if you have enabled the encoding of default values globally in your format configuration, you can override this behaviour to not encode the default for a specific property:

    @Serializable
    data class TestClass(
        val obligatory: String,
        @EncodeDefault(EncodeDefault.Mode.NEVER)
        val optional: Int = 0,
    )
    
    val json = Json { encodeDefaults = true }
    // then this will NOT encode the default, despite the format's config
    json.encodeToString(TestClass("text"))