Question
Hi I'm new to kotlinx serialization. the json is snake case, and kotlin data class uses camel case. is there a way to parse snake case by using custom serilizer and deserializer?
I know how to do...
val format = Json { namingStrategy = JsonNamingStrategy.SnakeCase }
val project = format.decodeFromString<Project>("""{"project_name":"kotlinx.coroutines", "project_owner":"Kotlin"}""")
assertThat(project.projectName).isEqualTo("kotlinx.coroutines")
assertThat(project.projectOwner).isEqualTo("Kotlin")
but I want to override deserializer and place this logic inside of companion object. is this possible?
My code
import kotlinx.serialization.KSerializer
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import kotlinx.serialization.descriptors.PrimitiveKind
import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor
import kotlinx.serialization.descriptors.SerialDescriptor
import kotlinx.serialization.encodeToString
import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder
import kotlinx.serialization.encoding.decodeStructure
import kotlinx.serialization.json.Json
import kotlinx.serialization.json.JsonNamingStrategy
@kotlinx.serialization.ExperimentalSerializationApi
private val json = Json { namingStrategy = JsonNamingStrategy.SnakeCase }
@Serializable(PaymentInfo.Companion::class)
data class PaymentInfo(
val paymentNo: String,
val paymentDate: String,
val paymentService: String,
) {
companion object: KSerializer<PaymentInfo> {
// what descriptor should I use?
override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("PaymentInfo", PrimitiveKind.)
override fun serialize(encoder: Encoder, value: PaymentInfo) {
// what to do ?
}
override fun deserialize(decoder: Decoder): PaymentInfo {
// what to do ?
}
}
}
Edited
I want to avoid adding @SerialName
to every member!
@SerialName
First, I just want to mention that I don't understand your wish to avoid
@SerialName
. You mentioned:But as you'll see in the next section of this answer, the custom serializer is quite a bit of code. And the same thing can be accomplished with just:
For something as simple as changing the serial name of a property, I strongly recommend you use
@SerialName
instead of writing a completely custom serializer.Custom Serializer
If you really want to avoid
@SerialName
, then you can customize the serialized names via a custom serializer. If you have:And you want the following custom names:
paymentNo
payment_no
paymentDate
payment_date
paymentService
payment_service
Then the custom
PaymentInfoSerializer
might look like this:See the Serializers chapter of the Kotlin Serialization Guide for more information.
Here is the above serializer in use:
Which gives the following output: