Skip to content

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

@marcosalis

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

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions