Skip to content

Undocumented behavior on serialization of non-constructor property with defaults #1803

Description

@marcosalis

Using moshi-kotlin:1.15.1 with KotlinJsonAdapterFactory:

Moshi.Builder().add(KotlinJsonAdapterFactory()).build()

I want to serialize the following model:

private data class WithDefaultValue(val property: String = "default") {
    val nonConstructor: String = "default"
}

I would expect the class JSON serialization to yield the following output:

{"property":"default","nonConstructor":"default"}

(and this, in fact, was what happened until Moshi <= 1.8)

But I get the following on the latest Moshi:

{"property":"default"}

The property outside the primary constructor is ignored. I would consider this an undocumented behavior and I honestly struggle to understand why this is happening. I would expect the property to be serialized since it's not marked as @Transient or @Json(ignored=true). Note that this also happens with normal (non data) classes.

The kotlin-serialization library allows to configure this aspect of encoding with the option encodeDefaults=true. I couldn't find anything equivalent in Moshi.

I have a legacy codebase with 300+ request/response models, and making one-by-one changes to the classes would be both unfeasible and extremely error-prone. Is there a way around this?
Thank you in advance.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions