8000 Override property with subtype during inheritance · Issue #372 · cjbooms/fabrikt · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content
Override property with subtype during inheritance #372
Open
@rajki

Description

@rajki

Hey folks 👋
Firstly great job with the playground, it's incredibly useful and a great time saver for iterations.

I wanted to get your opinion on the following usecase.

Assume that there are two type of Actions- DanceAction and WorkAction. There are equivalently two Locations- Home and Workplace. DanceAction can only be performed at Home, and WorkAction can only be performed at Work.

This can be represented in Kotlin as follows,

sealed class Action {
    abstract val location: Location
}

sealed class Location

data object Home : Location()

data object Work : Location()

data class DanceAction(
    override val location: Home,
) : Action()

data class WorkAction(
    override val location: Work,
) : Action()

Given an OpenAPI as follows,

openapi: 3.1.0
info:
  title: Action API
  version: 1.0.0

components:
  schemas:
    Action:
      type: object
      required:
        - location
      properties:
        location:
          $ref: '#/components/schemas/Location'
      discriminator:
        propertyName: location
        mapping:
          Home: '#/components/schemas/Home'
          Work: '#/components/schemas/Work'

    Location:
      type: object
      discriminator:
        propertyName: type
        mapping:
          Home: '#/components/schemas/Home'
          Work: '#/components/schemas/Work'
      properties:
        type:
          type: string
          enum: [Home, Work]

    Home:
      allOf:
        - $ref: '#/components/schemas/Location'

    Work:
      allOf:
        - $ref: '#/components/schemas/Location'

    DanceAction:
      allOf:
        - $ref: '#/components/schemas/Action'
        - type: object
          properties:
            location:
              $ref: '#/components/schemas/Home'

    WorkAction:
      allOf:
        - $ref: '#/components/schemas/Action'
        - type: object
          properties:
            location:
              $ref: '#/components/schemas/Work'

Fabrikt currently generates the following code (trimmed imports for brevity),

// Action
package com.example.models

@JsonTypeInfo(
  use = JsonTypeInfo.Id.NAME,
  include = JsonTypeInfo.As.EXISTING_PROPERTY,
  property = "location",
  visible = true,
)
@JsonSubTypes()
public sealed class Action(
  public open val location: Location,
)

// Location
package com.example.models

@JsonTypeInfo(
  use = JsonTypeInfo.Id.NAME,
  include = JsonTypeInfo.As.EXISTING_PROPERTY,
  property = "type",
  visible = true,
)
@JsonSubTypes(JsonSubTypes.Type(value = Home::class, name = "Home"),JsonSubTypes.Type(value =
    Work::class, name = "Work"))
public sealed class Location() {
  public abstract val type: LocationType
}

// LocationType
package com.example.models

public enum class LocationType(
  @JsonValue
  public val `value`: String,
) {
  HOME("Home"),
  WORK("Work"),
  ;

  public companion object {
    private val mapping: Map<String, LocationType> = entries.associateBy(LocationType::value)

    public fun fromValue(`value`: String): LocationType? = mapping[value]
  }
}

// Home
package com.example.models

public data class Home(
  @get:JsonProperty("type")
  @get:NotNull
  @param:JsonProperty("type")
  override val type: LocationType = LocationType.HOME,
) : Location()

// Work
package com.example.models

public data class Work(
  @get:JsonProperty("type")
  @get:NotNull
  @param:JsonProperty("type")
  override val type: LocationType = LocationType.WORK,
) : Location()

// DanceAction
package com.example.models

public data class DanceAction(
  @param:JsonProperty("location")
  @get:JsonProperty("location")
  @get:NotNull
  @get:Valid
  override val location: Location,
) : Action(location)

// WorkAction
package com.example.models

public data class WorkAction(
  @param:JsonProperty("location")
  @get:JsonProperty("location")
  @get:NotNull
  @get:Valid
  override val location: Location,
) : Action(location)

Please note the location field in WorkAction being of type Location instead of Work. Do you feel it would be idiomatic to support this?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      0