5

In a Microprofile / Quarkus project using Kotlin have a data class with a variable of type Instant.

@Schema(name = "Vehicle", description = "POJO that represents a vehicle at a specific time.")
data class VehicleDTO(
    var time: Instant = Instant.EPOCH
)

The problem is that the generated openapi schema does not represent how the value of Instant is actually transmitted.

The schema looks like the following, whereas it is simply represented as a string like that: 2015-06-02T21:34:33.616Z.

Instant:
  type: object
  properties:
    nanos:
      format: int32
      type: integer
    seconds:
      format: int64
      type: integer
    epochSecond:
      format: int64
      type: integer
    nano:
      format: int32
      type: integer

I already tried to annotate the data class to use the implementation string and type string, but it does not change anything.

@Schema(name = "Vehicle", description = "POJO that represents a vehicle at a specific time.")
data class VehicleDTO(
    @Schema(implementation = String::class, type = SchemaType.STRING)
    var time: Instant = Instant.EPOCH
)
Flickster
  • 120
  • 2
  • 9

1 Answers1

10

The issue is that data classes receive a bit of special treatment and your annotation is placed on the constructor argument.

You can see this in the generated Java code of your data class. Relevant snippet:

@Schema(
   name = "Vehicle",
   description = "POJO that represents a vehicle at a specific time."
)
@Metadata(...)
public final class VehicleDTO {
   @NotNull
   private Instant time;

   @NotNull
   public final Instant getTime() {
      return this.time;
   }

   public final void setTime(@NotNull Instant var1) {
      Intrinsics.checkParameterIsNotNull(var1, "<set-?>");
      this.time = var1;
   }

   public VehicleDTO(@Schema(implementation = String.class,type = SchemaType.STRING) @NotNull Instant time) {
      Intrinsics.checkParameterIsNotNull(time, "time");
      super();
      this.time = time;
   }

   // ...
}

You need to tell Kotlin to place it on the field using a use-site target:

@Schema(name = "Vehicle", description = "POJO that represents a vehicle at a specific time.")
data class VehicleDTO(
    @field:Schema(implementation = String::class, type = SchemaType.STRING)
    var time: Instant = Instant.EPOCH
)

Relevant code afterwards:

@Schema(
   name = "Vehicle",
   description = "POJO that represents a vehicle at a specific time."
)
@Metadata(...)
public final class VehicleDTO {
   @Schema(
      implementation = String.class,
      type = SchemaType.STRING
   )
   @NotNull
   private Instant time;

   @NotNull
   public final Instant getTime() {
      return this.time;
   }

   public final void setTime(@NotNull Instant var1) {
      Intrinsics.checkParameterIsNotNull(var1, "<set-?>");
      this.time = var1;
   }

   public VehicleDTO(@NotNull Instant time) {
      Intrinsics.checkParameterIsNotNull(time, "time");
      super();
      this.time = time;
   }

   // ...
}
Marvin
  • 13,325
  • 3
  • 51
  • 57