Haf
Haf

Reputation: 577

Generate `LocalTime` from OpenAPI specification

I see that there is a date format for strings in OpenAPI, and that by using dateLibrary=java8 we can generate LocalDate fields by using openapi-generator.

But is there any way of producing LocalTime fields? There is no time format in OpenAPI and the date-time one produces OffsetDateTime.

EDIT: It's hard offering a reproducible example since the question is about something I can't do, but some illustrative example would be that I want something along the lines of:

A schema specification:

Visit:
  type: object
  parameters:
    visitor:
      type: string
    timeOfVisit:
      type: string
      format: time

But obviously the time format is not present in the OpenAPI specification. The generated code should be something like

public class Visit {
  private String visitor;
  private LocalTime timeOfVisit;

  // Getters, setters, etc
}

There must surely be some way for openapi-generator to produce this output, isn't it? I've found that there are some import-mappings that map LocalTime to org.joda.time.* so there seems to be a way of having it produce LocalTime types, but I haven't found it

Upvotes: 5

Views: 17158

Answers (4)

Shehan Simen
Shehan Simen

Reputation: 1316

I use maven openapi-generator-maven-plugin plugin in my springboot app. This is my pom plugin configuration for this plugin:

<plugin>
            <groupId>org.openapitools</groupId>
            <artifactId>openapi-generator-maven-plugin</artifactId>
            <version>7.0.1</version>
            <executions>
                <execution>
                    <goals>
                        <goal>generate</goal>
                    </goals>
                    <configuration>
                        <inputSpec>${project.artifactId}-merged-spec.yaml</inputSpec>
                        <mergedFileName>${project.artifactId}-merged-spec</mergedFileName>
                        <inputSpecRootDirectory>${project.basedir}/src/main/resources/specs</inputSpecRootDirectory>
                        <output>${project.basedir}</output>
                        <generatorName>spring</generatorName>
                        <apiPackage>com.xxxx.openapi.yyyy.api</apiPackage>
                        <modelPackage>com.xxxx.openapi.yyyy.dto</modelPackage>
                        <modelNameSuffix>Dto</modelNameSuffix>
                        <generateSupportingFiles>false</generateSupportingFiles>
                        <typeMappings>
                            <typeMapping>string+localDateTime=LocalDateTime</typeMapping>
                            <typeMapping>string+localTime=LocalTime</typeMapping>
                        </typeMappings>
                        <schemaMappings>  
                            
                            <mapping>LocalDateTime=java.time.LocalDateTime</mapping>
                            <mapping>LocalTime=java.time.LocalTime</mapping>                                
                        </schemaMappings>
                        <configOptions>
                            <library>spring-boot</library>
                            <useSpringBoot3>true</useSpringBoot3>
                            <hideGenerationTimestamp>true</hideGenerationTimestamp>
                            <interfaceOnly>true</interfaceOnly>
                            <openApiNullable>false</openApiNullable>
                            <skipDefaultInterface>true</skipDefaultInterface>
                            <useBeanValidation>false</useBeanValidation>
                            <unhandledException>true</unhandledException>
                            <useTags>true</useTags>
                            <additionalModelTypeAnnotations>
                                @com.fasterxml.jackson.annotation.JsonInclude(com.fasterxml.jackson.annotation.JsonInclude.Include.NON_NULL)
                            </additionalModelTypeAnnotations>
                        </configOptions>
                    </configuration>
                </execution>
            </executions>
        </plugin>

Then in the open-api yaml, I have the declaration field like this:

    fromTime:
      type: string
      format: localTime
      example: '14:30:15'
    toTime:
      type: string
      format: localTime
      example: '14:30:15'

Upvotes: 0

Haf
Haf

Reputation: 577

Solved it! Actually it was really easy, but being a beginner in OpenAPI it was hard finding a solution. Given the example in my question, I'd just have to run openapi-generator-cli as

openapi-generator-cli generate -g java --type-mappings time=LocalTime

And voilà, it's done!

EDIT: This would make the field type become LocalTime, but the compiler will complain that the type is not imported. The import can be added using the previously (in the question) mentioned import-mappings, so the definitive command would be:

openapi-generator-cli generate -g java --type-mappings time=LocalTime --import-mappings LocalTime=java.time.LocalTime

EDIT:

An alternative is to configure the plugin inside your pom.xml:

<configuration>
    <typeMappings>
        <typeMapping>time=LocalTime</typeMapping>
    </typeMappings>
    <importMappings>
        <importMapping>LocalTime=java.time.LocalTime</importMapping>
    </importMappings>
</configuration>

Upvotes: 9

mflorczak
mflorczak

Reputation: 363

If you are using spring with gradle you need to add this two properties to build.gradle

openApiGenerate() {
    generatorName = "spring"
    ...
    typeMappings = ["time": "LocalTime"]
    importMappings = ["LocalTime": "java.time.LocalTime"]
}

So this configuration will say that format: time will generate LocalTime type and java.time.LocalTime here is the source of this type.

Upvotes: 3

Elias Khan
Elias Khan

Reputation: 95

I have found that there is a dateLibrary option in the configOptions tag in the pom.xml. This way I didn't have to map manually between OffsetDateTime (which was being generated at first) and LocalDateTime.

If you add true to the configuration tag it will print out all the options.

dateLibrary
        Option. Date library to use (Default: threetenbp)
            joda - Joda (for legacy app only)
            legacy - Legacy java.util.Date (if you really have a good reason not to use threetenbp
            java8-localdatetime - Java 8 using LocalDateTime (for legacy app only)
            java8 - Java 8 native JSR310 (preferred for jdk 1.8+) - note: this also sets "java8" to true
            threetenbp - Backport of JSR310 (preferred for jdk < 1.8)

Upvotes: 3

Related Questions