3

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

2 Answers 2

7

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.

Sign up to request clarification or add additional context in comments.

5 Comments

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-annotations, thanks! Why do you propose a different solution for date-time? Is it also possible to use an x-field-extra-annotation there?
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.
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?
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
How can I easily add something to a schema if I'm integrating to some service, which is the point of using openapi? I don't have the schema under control...
0

As openapi-generator chose not to configure the serialization of LocalDate to string (hence breaking the type read from yaml string format date) on payload, the error may occur if you build your WebClient yourself. Use provied static methods instead as follows

ApiClient apiClient = new ApiClient(
            ApiClient.buildWebClientBuilder()
            // do other WebClient configurations
            .build());

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.