2

I am using the OpenAPI java generator [1] with library:resttemplate, dateLibrary:java8 in a spring project to generate a client from a spec.

For a property in the spec:

        targetDate:
          type: string
          format: date

the following code is generated:

  public static final String JSON_PROPERTY_TARGET_DATE = "targetDate";

  private LocalDate targetDate;

  @javax.annotation.Nonnull
  @JsonProperty(JSON_PROPERTY_TARGET_DATE)
  @JsonInclude(value = JsonInclude.Include.ALWAYS)

  public LocalDate getTargetDate() {
    return targetDate;
  }

  @JsonProperty(JSON_PROPERTY_TARGET_DATE)
  @JsonInclude(value = JsonInclude.Include.ALWAYS)
  public void setTargetDate(LocalDate targetDate) {
    this.targetDate = targetDate;
  }

I would expect this field to be serialized to a full date e.g. "2023-01-01" as promised by the spec: https://spec.openapis.org/oas/v3.0.0#data-types. However it is in fact serialized to an array: [2023,1,1].

Similarly another property

        otherDate:
          type: string
          format: date-time

is serialized to seconds since epoch, instead of full-time. (I assume this is a bug in the generator)

I cannot add any annotations since the code is generated. How can I still ensure that the date is properly serialized?

[1] openapi-generator-maven-plugin 6.3.0

peer
  • 4,171
  • 8
  • 42
  • 73

1 Answers1

6

Your issues are not generator related, they are Jackson related.

Regarding your DateTime being in the wrong format, this is the default way that Jackson will serialize a LocalDate object when it uses the JavaTimeModule. This is discussed on this post, when the user is specifically asking for an array serialization. This can be fixed by setting the format you want, which is answered here.

The basic gist is this. You need to set the @JsonFormat annotation above your field. You say that you cannot add any annotations, but this is also incorrect. You can easily add the @JsonFormat annotation to your code by setting the x-field-extra-annotation extension in your schema. For example:

targetDate:
  type: string
  format: date
  x-field-extra-annotation: '@com.fasterxml.jackson.annotation.JsonFormat(shape = com.fasterxml.jackson.annotation.JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd")'

This will result in the following code being generated

@com.fasterxml.jackson.annotation.JsonFormat(shape = com.fasterxml.jackson.annotation.JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd")
private LocalDate targetDate;

As for the date-time being serialized as seconds since epoch, this is a vary easy setting in Jackson. You can disable the SerializationFeature.WRITE_DATES_AS_TIMESTAMPS. This will result in the ISO-8601 standard string.

tbatch
  • 1,398
  • 10
  • 21
  • I maintain that this is a generator bug, as I expect the generator to add the appropriate Jackson annotations. I did not know about `x-field-extra-annotation`s, thanks! Why do you propose a different solution for `date-time`? Is it also possible to use an `x-field-extra-annotation` there? – peer Apr 04 '23 at 09:00
  • 1
    This is not a bug, but a conscious decision on the part of the developers. You said you are using the `java` generator with the `resttemplate` library. By default, the `resttemplate` library generates a class called `RFC3339DateFormat`, and a class called `JavaTimeFormatter`. You can examine the code in the `ApiClient` and see how the formatters are used, and you can also easily add your own format to them by modifying the mustache templates used to generate the formatters and the `ApiClient`. – tbatch Apr 04 '23 at 13:35
  • Solution is working fine except with bad input in request the system (spring) return SERVER_ERROR instead of BAD_REQUEST. Did you have this issue? – Martin P. Jun 15 '23 at 13:11
  • Found the solution need to catch the exception when getting the field. It seem to do the parsing when I call the getter. So simple and well done – Martin P. Jun 15 '23 at 13:19