Description
Swagger specifications allow models to be polymorphic via a discriminator
field (doc).
This allows a model, let's say Animal
to be a sort of parent in the hierarchy of other types like Dog
, Cat
, etc.
The polymorphic approach is generally interesting when an endpoint is returning a base object (ie. Animal
) that can be specified more detailed by related type or when your endpoint returns a list of mixed objects.
Retrofit example
class Animal(open var type: String)
data class Dog(override var type: String, var name: String): Animal(type=type)
data class Cat(override var type: String, var size: Int): Animal(type=type)
@JvmSuppressWildcards
interface SwaggerApi {
@GET("/animals")
fun getAnimals(): Single<List<Animal>>
}
The endpoint GET /animals
might be returning a JSON similar to
[
{"type": "dog", "name": "name"},
{"type": "cat", "size": 1},
{"type": "whale", "weight": 42}
]
and ideally we should be able to decode it as
listOf(
Dog(type="dog", name="name"),
Cat(type"cat", size=1),
Animal(type="whale")
)
Without real support for polymorphism (as for version 1.3.0) the response would be decoded as
listOf(
Animal(type="dog"),
Animal(type="cat"),
Animal(type="whale")
)
which leads to some information loss (the dog name was sent to the client and the client should have known about it)
Disclaimer: The above presented example is mostly to help understand the feature that polymorphism brings to codegen.
An other possibility might be to define inheritance via sealed classes
sealed class Animal(open var type: String) {
data class DefaultAnimal(override var type: String): Animal(type=type) // How to pick a name that has not been used yet?
data class Dog(override var type: String, var name: String): Animal(type=type)
data class Cat(override var type: String, var size: Int): Animal(type=type)
}
Does someone have other ideas?