I have an interface for Events that has multiple c...
# serialization
n
I have an interface for Events that has multiple concrete sealed class implementations, like so:
Copy code
// in package com.example.platform
interface Event

// in package com.example.customer
@Serializable
sealed class CustomerEvent : Event {
    object CustomerEvent1
    ...
}

// in package com.example.supplier
@Serializable
sealed class SupplierEvent : Event {
    object SupplierEvent1
    ...
}
I would like to be able to serialize/deserialize
Event
, but I don't really want to have all the event trees in one package, so using one big
sealed class
hierarchy doesn't work well. Does anyone have any idea how to go about registering
Event
as polymorphically serializable?
I tried registering
Event
as polymorphic:
Copy code
SerializersModule {
    polymorphic(Event::class) {
        subclass(CustomerEvent::class, CustomerEvent.serializer())
        subclass(SupplierEvent::class, SupplierEvent.serializer())
    }
}
But I get this error:
Copy code
Serializer for Event can't be registered as a subclass for polymorphic serialization because its kind SEALED is not concrete. To work with multiple hierarchies, register it as a base class.
What does work is adding each concrete class to the
polymorphic
block, but there are dozens of them and that's liable to get forgotten over time as we add more.
f
'register it as a baseclass', there might be something akin to baseclass() you can use instead of subclass()
Or maybe do polymorphic() instead of subclass()
Also try subclass(CustomEvent.serializer())
d
Register the concrete classes not the sealed class. (or you can do
polymorphic
for each subclass, as Fudge says)
e
register them all as polymorphic, if you're worried about missing one then add a test which can reflectively check all subclasses
n
K, I was afraid that was the answer. Thanks.
e
well, if you want to live dangerously, you could always to the sketchy reflection stuff in production
I recommend against it, though
one thing you can do is have a SerializersModule per package, and just
+
them all together; that way the various
polymorphic(...)
registrations are closer to the declarations, e.g.
Copy code
// in package com.example.customer
val serializersModule = SerializersModule {
    polymorphic(Event::class, CustomerEvent.CustomerEvent1::class, CustomerEvent.CustomerEvent1.serializer())
}

// in package com.example.supplier
val serializersModule = SerializersModule {
    polymorphic(Event::class, SupplierEvent.SupplierEvent1::class, SupplierEvent.SupplierEvent1.serializer())
}

// at serialization usage site
val json = Json {
    serializersModule = com.example.customer.serializersModule + com.example.supplier.serializersModule
}