How to disable kotlinx serialization polymorphic descriminator?

Viewed 1116

I'm generating JSON for a number of third-party APIs. Many of them accept a list (JSON array) of different objects, however, none of them will accept the "type": "com.mycom.someclass" automatically generated by kotlinx serialization due to the polymorphic nature of the list.

In my use-case, I only care about serializing out. No deserialization is needed.

Current:

[{"type":"com.mycom.Child1","x":"child1"}, {"type":"com.mycom.Child2","y": 23}]

Needed:

[{"x":"child1"}, {"y": 23}]

How can I disable this automatic behavior?

2 Answers

Take a look at Json parametric polymorphic deserialization:

You also can serialize data with such serializer. In that case, either registered or default serializer would be selected for the actual property type in runtime. No class discriminator would be added.

You'll need to impelement JsonParametricSerializer and manually select the serializer. As you don't need to support deserialization, the implementation would be trivial.

The trick is to make the polymorphic type distinctive. As an example

sealed class Vehicle {
   data class Car(...)
   data class Bike(...)
}

val v: Vehicle = Vehicle.Car()

// Contains "type" as you serialize Vehicle, which is polymorphic
val json1 = Json.encodeToString(v) 

// Does not contain "type" as you serialize Vehicle.Car, which is distinctive
val json2 = when(v) {
    is Vehicle.Car -> Json.encodeToString(v)
    is Vehicle.Bike -> Json.encodeToString(v)
} 

Same when you'd use this in Ktor:

// Contains "type" as you serialize Vehicle, which is polymorphic
setBody(v) 

// Does not contain "type" as you serialize Vehicle.Car, which is distinctive
val json2 = when(v) {
    is Vehicle.Car -> setBody(v)
    is Vehicle.Bike -> setBody(v)
} 
Related