
openapi-processor is a small framework that converts an OpenAPI 3.2, 3.1 or 3.0 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.
-
it is easy to document in plain text. You can use Markdown in the OpenAPI
descriptionproperties. -
no need to manually write controller annotations and remember all the annotation details.
-
you can skip generation of single endpoints that have special (unsupported) requirements and write them manually.
-
generating only interfaces (and DTOs) for the endpoints minimizes the constraints for implementing the endpoint methods.
-
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.
supported OpenAPI versions
it supports OpenAPI 3.2 (since 2025.5), 3.1 and 3.0. |
supported target formats
creates Spring Boot java interfaces & DTOs (POJOs or records) from the OpenAPI description using Spring annotations. |
|
creates Micronaut java interfaces & DTOs (POJOs or records) from the OpenAPI description using Micronaut annotations. |
|
converts the OpenAPI YAML description to JSON format. It inlines all |
|
supported build tools
a few things it can do …
it generates Java interfaces and DTOs (POJO or Record) classes for all defined endpoints and schemas to allow full control of the endpoint implementation.
It generates human-readable code, and if that is not enough, it can re-format the code by passing it to a code-formatter.
package io.openapiprocessor.samples.foo;
import io.openapiprocessor.openapi.support.Generated;
import jakarta.validation.Valid;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
@Generated( value = "openapi-processor-spring", version = "...")
public interface FooApi {
/**
* echo a Foo. simple sample endpoint
*
* @return foo
*/
@PostMapping(
path = "/foo",
consumes = {"application/json"},
produces = {"application/json"})
Foo postFoo(@RequestBody(required = false) @Valid Foo body);
}
package io.openapiprocessor.samples.foo;
import com.fasterxml.jackson.annotation.JsonProperty;
import io.openapiprocessor.openapi.support.Generated;
import jakarta.validation.constraints.Size;
import java.util.UUID;
/**
* Foo object description
*
* @param foo foo property description
* @param id id property description
*/
@Generated( value = "openapi-processor-spring", version = "...")
public record Foo(@Size(max = 10) @JsonProperty("foo") String foo, @JsonProperty("id") UUID id) {
}
it has a powerful type mapping configuration (with generic support, allows nesting) to map schemas defined in the OpenAPI description to existing Java types.
Mappings can be defined globally, for an endpoint, response, parameter or HTTP method. More specific mappings override less specific mappings.
openapi-processor-mapping: v17
options:
# ...
map:
types: # list of global mappings
- type: array => java.util.Collection
- type: string:date-time => java.time.Instant
paths:
# endpoint mappings
/endpoint:
types:
# generated DTO implements Serializable
- type: Schema =+ java.io.Serializable
parameters:
# map parameters
- name: foo => java.util.List
- add: bar => java.util.Set
responses:
# map responses
- content: application/vnd.any => java.util.Set
- content: application/json => java.util.Map
# HTTP method mappings
get:
types:
- type: Foo => MappedFoo
it offers annotation mapping to add additional annotations to the DTOs generated from the OpenAPI schemas.
openapi-processor-mapping: v17
options:
# ...
map:
types:
# add an annotation to the OpenAPI schema Foo
# (the annotation may have parameters)
- type: Foo @ annotation.Bar()
it can generate code into Java packages by placing OpenAPI YAML fragments into the desired package and $ref ing it from the main openapi.yaml. This works best with OpenAPI 3.2 and the new $self property.
The processor will generate the code based on foo.yaml and resources.yaml into the io.openapiprocessor.samples.foo package.
sample
\---- src
+---- api
| +---- mapping.yaml
| \---- openapi.yaml
\---- main
+---- kotlin
| +---- io
| | \---- openapiprocessor
| | \---- samples
| | +---- foo
| | | +---- FooController.kt
| | | +---- foo.yaml
| | | \---- resources.yaml
| | \---- bar
| | \---- ...
\---- resources
\---- application.properties
it can map OpenAPI x- tensions to add additional annotations to schema properties.
openapi-processor-mapping: v17
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 handles relative $ref 's between multiple OpenAPI YAML/JSON files.
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 can drop parameters of an endpoint defined in the OpenAPI description. This may be useful if a parameter is handled by a request filter and therefore is not needed in the endpoint method anymore.
it can generate marker interfaces for responses instead of using Object in case an endpoint has multiple different responses. This makes code navigation easier.
it supports bean validations (javax and jakarta). The constraints of the OpenAPI description map to java bean validation annotations.
it supports JSON merge patch apis by generating DTOs with jackson-databind-nullable where requested.
it 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.
it handles multiple responses by generating one endpoint method for each response content type.
It is stable. It has a large test suite with unit tests and integration tests. The integration tests run the processor on OpenAPI descriptions and check/compile the generated output.