openapi-processor-spring

badge License Apache%202.0 blue

openapi-processor-spring is an OpenAPI interface & model java code generator for Spring Boot.

It supports an approach where you explicitly define and document your Service API (using OpenAPI) with the Interface to the outside and its usage in mind before you implement it. You do not derive the API later from the implementation and its implicit design. (of course, adapt as you go…​)

The advantages are:

  • you have a single place to maintain the api which makes it easier to create a consistent api and keep the overview.

  • it is easy to document in plain text. You can use markdown in the OpenAPI description properties.

The processor generates java interfaces based on the endpoint description of the API and simple POJO classes for parameter or response objects defined in the API. The processor adds all the required spring & jackson annotations to the interface and all that is left to you is the implementation of the generated interfaces in any way you like.

The interfaces will help to keep the implementation in sync with the API. If anything relevant changes in the API the interface changes and the compiler will warn that the interface is not implemented correctly.

The target programming language is Java so the generated code is usable from most JVM languages.

See the processor intro for a short example.

Playground

openapi-processor has a playground application. You can try out some samples, or your own yaml and view the code that the processor generates.

Features

  • generates only java interfaces and java model classes (get/set POJOs) for all defined endpoints and schemas to allow full control of the endpoint implementation. It does not generate any other file. See processor.

  • powerful type mappings with generic support (one level) to map schemas defined in the openapi.yaml to existing java types.

    For example to map the openapi array type to a different java collections or to map paging parameters and results to th Spring types like Page<> & Pageable.

    mappings can be defined globally or for a specific response or parameter or even only for a specific endpoint. See type mapping.

  • Annotation based WebFlux support. Actually there is no explicit WebFlux support, but the mapping allows defining a single, and a multi wrapper class. single wraps non-array like result types (e.g. Mono<>). multi replaces array like result types or parameters with the given multi mapping. For example, it will replace List<String> with Flux<String> if the multi mapping contains the fully qualified Flux type.
    since 1.0.0.M13

  • generates human readable code.

  • add additional parameters to an endpoint which are not defined in the OpenAPI description. For example to pass a HttpServletRequest to the endpoint implementation.
    since 1.0.0.M6

  • supports bean validations. The constraints of the openapi description map to java bean validation annotations.
    since 1.0.0.M6

  • allows excluding endpoints from generation. This is useful if the processor does not create the correct code for an endpoint. That way the processor can still be used for all the other endpoints.
    since 1.0.0.M6

  • handle multiple responses by generating one endpoint method for each response content type.
    since 1.0.0.M11

  • the generated code does not use swagger annotations. There is no need to generate the documentation from the code when the code originates from the documentation (i.e. an openapi.yaml).

    The generated source code has to be included in a project to compile it. This is easily done with the openapi-processor-gradle plugin. See Using Gradle.
  • gradle support via openapi-processor-gradle plugin (the plugin is currently the only option to run the processor).

Releases

See the release notes to find the latest release. The full artifact name is:

in gradle short notation
    io.openapiprocessor:openapi-processor-spring:<version>

Feedback

In case some feature is missing, or the generated code is not 100% what you would expect create an issue. Preferably with a test case. Providing a test case will help significantly :-)

A test case is a single folder with two subfolders containing the source files, and the expected output files:

my-test-case
+--- inputs.yaml
|--- inputs
|    +--- mapping.yaml
|    \--- openapi.yaml
+--- generated.yaml
\--- generated
     +--- api
     |    \--- EndpointApi.java
     \--- model
          \--- Foo.java

inputs.yaml and generated.yaml use the same simple format:

items:
   - inputs/openapi.yaml
   - inputs/mapping.yaml

or

items:
   - generated/api/EndpointApi.java
   - generated/model/Foo.java

See the existing integration tests for some examples.