Kotlin / kotlinx.serialization

Kotlin multiplatform / multi-format serialization
Apache License 2.0
5.41k stars 620 forks source link

JsonNamingStrategy.SnakeCase with CamelCase API #2276

Closed JJSarrasin closed 1 year ago

JJSarrasin commented 1 year ago

All my libraries and tools are up-to-date (stable versions).

All the content of the APIs I'm reaching are in snake_case, that's why I use the namingStrategy JsonNamingStrategy.SnakeCase

Only one route's content is in CamelCase, I'm trying to define my object like this:

@Serializable
class Quotas {
    @SerialName("RecQuotaUsed")
    var recQuotaUsed: Int = 0

    @SerialName("RecQuotaMax")
    var recQuotaMax: Int = 0

    @SerialName("ArchiveQuotaUsed")
    var archiveQuotaUsed: Int = 0

    @SerialName("ArchiveQuotaMax")
    var archiveQuotaMax: Int = 0
}

The JSON I get:

{
    "RecQuotaUsed": 23667,
    "RecQuotaMax": 60000,
    "ArchiveQuotaUsed": 1167,
    "ArchiveQuotaMax": 1200
}

And when I print my values, all of them are 0. Any idea why ? Wrong use or bug in the converter ?

JJSarrasin commented 1 year ago

One addition, I just find out that if I use @JsonNames instead of @SerializedName, it works.

sandwwraith commented 1 year ago

It is per documentation for JsonNamingStrategy (https://kotlinlang.org/api/kotlinx.serialization/kotlinx-serialization-json/kotlinx.serialization.json/-json-naming-strategy/):

Due to the nature of kotlinx.serialization framework, naming strategy transformation is applied to all properties regardless of whether their serial name was taken from the property name or provided by @SerialName annotation. Effectively it means one cannot avoid transformation by explicitly specifying the serial name.

If one wants to preserve the original serial name for deserialization, one should use the JsonNames annotation, as its values are not transformed.