Skip to content

Support polymorphism #103

@macisamuele

Description

@macisamuele

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?

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions