logo

openapi-processor

openapi-processor is a small framework that converts an OpenAPI yaml (or json) descriptions to a target format. The primary target is Java code. It generates interfaces and DTOs (pojos or records) based on the API and you implement the interfaces in your controllers.

The target programming language is Java, which makes the generated code usable from most JVM languages.

starting with an API
openapi-processor is useful if 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, this is not a one time step but an iterative process.

The disadvantages are:

  • you have to learn OpenAPI & write the OpenAPI description.

  • the code generation has its limits and does not support all use cases.

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.

  • you don’t need to manually write the controller annotations and remember all the annotation details.

  • you can easily skip generation of endpoints that have special (unsupported) requirements and write them manually.

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

  • it helps to keep the implementation in sync with the OpenAPI description. If anything relevant changes in the API the interface changes and the compiler will warn that the interface is not implemented correctly.

code generation
A processor generates java interfaces based on the endpoint descriptions of the API and simple Pojo or Record classes for parameter or response schemas defined in the API with the help of the type mapping configuration. The processor adds all the required annotations to the interface and all that is left to you is the implementation of the generated interfaces in any way you like.

process

supported target formats

openapi processor spring?color=009051&label=latest

creates Spring Boot java interfaces & dtos (pojos or records) from the OpenAPI description using spring annotations.

openapi processor micronaut?color=009051&label=latest

creates Micronaut java interfaces & dtos (pojos or records) from the OpenAPI description using micronaut annotations.

supported build tools

openapi processor gradle?color=009051&include prereleases&label=latest

gradle plugin to run any processor from Gradle.

openapi processor maven plugin?color=009051&label=latest

maven plugin to run any processor from Maven.

.. a few things it can do

it generates java interfaces and java dtos (pojo/record) classes for all defined endpoints and schemas to allow full control of the endpoint implementation.

endpoint interface
package io.openapiprocessor.openapi.api;

import io.openapiprocessor.openapi.support.Generated;
import io.openapiprocessor.samples.MappedBar;
import jakarta.validation.Valid;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;

@Generated(value = "openapi-processor-spring", version = "2024.1")
public interface BarApi {

    /**
     * echo a Bar.
     * simple sample endpoint
     *
     * @return bar
     */
    @PostMapping(path = "/bar", consumes = {"application/json"}, produces = {"application/json"})
    MappedBar postBar(@RequestBody(required = false) @Valid MappedBar body);

}

it has a powerful type mapping configuration (with generic support) to map schemas defined in the OpenAPI description to existing java types. Mappings can be defined globally, for a specific response, parameter or endpoint or http method (of an endpoint).

global type mapping
openapi-processor-mapping: v6
options:
  # ...

map:
  types: # list of global mappings
    - type: array => java.util.Collection
    - type: string:date-time => java.time.Instant

it offers annotation mapping to add additional annotations to the dtos generated from the OpenAPI schemas.

global annotation mapping
openapi-processor-mapping: v6
options:
  # ...

map:
  types:
    # add an annotation to the OpenAPI schema Foo
    # (the annotation may have parameters)
    - type: Foo @ annotation.Bar()

it can map OpenAPI x- tensions to add additional annotations to schema properties.

global x-tension mapping
openapi-processor-mapping: v6
options:
  # ...

map:
  extensions:
    # map x-tension values to annotations
    x-foo: single @ io.oap.FooA(value = "any")
    x-bar:
      - listA @ io.oap.FooB
      - listB @ io.oap.FooC

it can add additional parameters to an endpoint which are not defined in the OpenAPI description. For example to pass an HttpServletRequest to the endpoint implementation which is nothing you want to describe in the API.

it generates human-readable code.

it supports bean validations. The constraints of the OpenAPI description map to java bean validation annotations.

it supports json merge patch apis by generating pojos with jackson-databind-nullable where requested.

it allows to exclude 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.

it handles multiple responses by generating one endpoint method for each response content type.

it handles relative $ref 's between multiple yaml files.

it is tested with handles relative $ref 's between multiple yaml files.