Reputation: 411
I'm looking for a standardized way to serialize a Kotlin object into a "flat" Json with only key -> value pairs using kotlinx.serialization on the JVM.
An Example:
@Serializable
data class Address(val street: String, val postalCode: String)
@Serializable
data class Customer(val id: String, val name: String, val address: Address)
The default behaviour upon serialization is:
{
"id": "123ABC",
"name": "Joe"
"address": {
"street": "my street",
"postalCode": "123456"
}
}
What i want is:
{
"id": "123ABC",
"name": "Joe"
"street": "my street",
"postalCode": "123456"
}
I could not find a way to accomplish this in the Kotlin Serialization Guide. Therefore I'm quite sure I have to implement a custom KSerializer<Customer>
but currently don't see how to achieve to behaviour.
Upvotes: 4
Views: 3859
Reputation: 7902
This could be done with surrogate serializer technique:
import kotlinx.serialization.descriptors.SerialDescriptor
import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder
import kotlinx.serialization.json.*
import kotlinx.serialization.*
@Serializable
data class Address(val street: String, val postalCode: String)
@Serializable(with = CustomerSerializer::class)
data class Customer(val id: String, val name: String, val address: Address)
@Serializable
@SerialName("Customer")
private data class CustomerSurrogate(val id: String, val name: String, val street: String, val postalCode: String)
object CustomerSerializer : KSerializer<Customer> {
override val descriptor: SerialDescriptor = CustomerSurrogate.serializer().descriptor
override fun deserialize(decoder: Decoder): Customer {
val surrogate = decoder.decodeSerializableValue(CustomerSurrogate.serializer())
return Customer(surrogate.id, surrogate.name, Address(surrogate.street, surrogate.postalCode))
}
override fun serialize(encoder: Encoder, value: Customer) {
val surrogate = CustomerSurrogate(value.id, value.name, value.address.street, value.address.postalCode)
encoder.encodeSerializableValue(CustomerSurrogate.serializer(), surrogate)
}
}
fun main() {
println(Json.encodeToString(Customer("123ABC", "Joe", Address("my street", "123456"))))
}
Upvotes: 7