Avaje OpenAPI Generators
avaje-openapi-maven-plugin reads an OpenAPI 3 YAML/JSON document and generates
Java source using Avaje annotations:
- API interfaces using
io.avaje.http.apiannotations (@Path,@Get,@Post,@QueryParam,@Header, ...) - DTO records and enums
- optional Avaje Jsonb annotations
- optional Jakarta or Avaje validation annotations
- optional Avaje Record Builder support for DTO records
The generated interfaces are then consumed by the existing Avaje annotation processors:
avaje-http-client-generatorgenerates typed HTTP clients- server generators (Nima/Helidon, Jex, Javalin) consume the same
avaje-http-apicontract avaje-jsonb-generatorgenerates JSON adapters for generated DTO recordsavaje-record-buildergenerates builders for generated DTO records when enabled
This is the contract-first workflow: the OpenAPI document is the single source of truth, and the same generated interface drives both the HTTP client and the server controller. See Contract-first client & server.
Getting started
Plugin setup
<plugin>
<groupId>io.avaje</groupId>
<artifactId>avaje-openapi-maven-plugin</artifactId>
<version>${avaje.openapi.version}</version>
<executions>
<execution>
<goals>
<goal>generate</goal>
</goals>
<configuration>
<inputSpec>${project.basedir}/src/main/openapi/openapi.yaml</inputSpec>
<apiPackage>org.example.api</apiPackage>
<modelPackage>org.example.api.model</modelPackage>
</configuration>
</execution>
</executions>
</plugin>
Generated contract source defaults to:
target/generated-sources/avaje-openapi
The plugin adds that directory to the Maven compile source roots automatically. See the full configuration reference for every option.
Interface path (@Path)
The class-level @Path on each generated interface is derived from two sources,
concatenated:
- the path component of the first
serversURL, then - the longest literal path prefix shared by every operation in that interface (the leading path segments common to all operations, stopping at the first path variable)
servers:
- url: https://api.example.com/v1 # absolute URL, or a relative "/v1"
paths:
/pets/{id}: { get: { tags: [store], ... } }
/owners/{id}: { get: { tags: [store], ... } }
generates:
@Path("/v1")
public interface StoreApi {
@Get("/pets/{id}")
Pet getPet(Long id);
@Get("/owners/{id}")
Owner getOwner(Long id);
}
The servers URL may be absolute (https://host/v1) or root-relative
(/v1); only its path component is used, a trailing / is trimmed, and a
bare / contributes nothing. Server URLs containing template variables
(https://{host}/v1) cannot form a static prefix and are ignored with a warning.
Equivalently you can omit servers and put the version directly in the paths
(/v1/pets/{id}); the shared /v1 segment is then picked up by the
common-prefix step.
Operations are grouped into interfaces by their first tag.
Java versions
The generator itself runs on Java 11+ (avaje-openapi-generator-core,
avaje-openapi-maven-plugin). Generated DTO models use Java records, so a project
that compiles the generated model source needs Java 17+ as a practical baseline.
A common arrangement is to publish the generated API + model module at Java 17 so that Java 17 consumers can use the generated HTTP client, while the server module that implements the contract runs on Java 21.
Current scope
Supported: OpenAPI 3 YAML/JSON; REST paths and common HTTP methods; JSON request/response
bodies; path/query/header/cookie parameters; component object schemas, enums, arrays, maps,
date/time/UUID formats; validation constraints; readOnly/writeOnly
fields; response headers as @apiNote; allOf composition; inline
schemas extracted into named nested records; description/summary as
Javadoc and deprecated as @Deprecated; @Nullable on
optional members; global dateTimeType, extended formats, x-java-type,
and typeMappings; convenience default method overloads.
Unsupported features currently produce diagnostics: oneOf/anyOf/discriminator
polymorphism; multipart upload; callbacks, links, webhooks; multiple request body content types
per operation.
Modules
| Module | Purpose |
|---|---|
avaje-openapi-generator-core |
Reusable OpenAPI parser and Java source generator |
avaje-openapi-maven-plugin |
Maven plugin exposing the avaje-openapi:generate goal |
avaje-openapi-sample |
Example project generating a contract, HTTP client, Nima/Helidon route, JSON adapters, and record builders |
Where to next
- Contract-first client & server — generating and wiring the client and server from the same interface
- DTO Models — record DTOs, builders, JSON, API-only generation
- Parameters — query/header/cookie params, defaults, nullable, overloads
- Type Mapping — date-time, primitives,
x-java-type,typeMappings - Validation — constraint styles and
@Validcascade - Configuration Reference — every plugin option