Grimm implements MicroProfile OpenAPI 4.2, which in turn rides on OpenAPI 3.1.0. This page lays out the vocabulary — Components, Paths, Operations, Schemas — and the mechanics of merging the various model sources.
The OpenAPI 3.1 model
The OpenAPI format describes an HTTP service through a structured JSON or YAML tree. Three top-level groups:
| Level | Role |
|---|---|
|
Contract metadata: title, version, license, contact, description. |
|
Operation catalogue. Each key is a path ( |
|
Reuse catalogue: |
The MP OpenAPI 4.2 spec’s Java model mirrors that structure: the OpenAPI interface → Info, Paths, Components. Grimm provides concrete implementations (records or final classes) in io.vidocq.grimm.internal.model, produced by its own OASFactoryResolver.
Three sources, one merge
The "Processing rules" of MP OpenAPI 4.2 prescribe three model sources, merged in this order (lowest to highest priority):
-
OASModelReader— an application class implementingorg.eclipse.microprofile.openapi.OASModelReader, selected viamp.openapi.model.reader. Lets you build theOpenAPIprogrammatically; it is the starting model. -
Static file —
META-INF/openapi.yaml,.ymlor.jsonpackaged in the classpath. Loaded byStaticFileReader. Acts as the "editorial skeleton" supplied by the design team. -
Annotation scan — visits every application class discovered by the CDI container:
@Pathresources, but also standalone carriers of@OpenAPIDefinition,@Server,@Tag,@SecuritySchemeor@Schema. Driven byAnnotationScanner.
ModelMerger combines the three with the spec priority annotations > static file > reader: the static file overrides the conflicting elements of the reader model, and the annotations override any conflicting element of both. The result is a single OpenAPI, dropped into GrimmModelCache.
NEW In 0.3.0 and earlier, Grimm merged the static file first and the reader on top of it, so on a conflict the reader won over the static file. It now follows the spec order above: the static file wins over the reader.
How the sources combine NEW
The sources are applied in the order above, each one on top of the result of the previous ones: reader, then static file, then annotations, and finally the OASFilter if one is configured. Two rules decide what happens when several sources describe the same element:
-
A named component schema is taken whole. When two sources define
components/schemas/Pet, the definition of the higher-priority source replaces the other one entirely. Properties of the lower-priorityPetthat the winner does not declare are not kept. -
Schemas at the same position are merged property by property. This covers the schema of a media type, the entries of a schema’s
properties, and itsitems. Every keyword the higher-priority source sets wins; keywords it does not set are kept from the lower-priority source. Extensions (x-*) are merged the same way. Explicit empty values from the higher-priority source are kept (default: [],const: {}, empty extensions); only an emptytype,enum,requiredorpropertiesdoes not erase what a lower-priority source says. A$refread from a static file is copied verbatim, with no short-name expansion.
|
OpenAPI 3.1 lets a Reference Object carry |
OASFilter filters
An application class implementing org.eclipse.microprofile.openapi.OASFilter can transform the document after merge, on an operation-by-operation basis. Activation via mp.openapi.filter=fqn.MyFilter. Grimm runs the filter in FilterInvoker, with a single top-down pass that dispatches on Operation, PathItem, APIResponse, Schema, Parameter and others.
|
The filter runs once, at document build time, not per request. It therefore has no access to |
Configuration via MicroProfile Config
MP OpenAPI 4.2 §4 defines a set of mp.openapi.* keys read through MicroProfile Config — supplied by Ravel in the Vidocq ecosystem.
| Key | Effect |
|---|---|
|
Disables annotation scanning altogether. |
|
Whitelist of packages to scan (comma-separated). |
|
Whitelist of specific classes. |
|
Packages excluded from the scan. |
|
Classes excluded. |
|
FQCN of the |
|
FQCN of the |
|
List of server URLs to enforce on the document. |
|
JSON snippet defining a schema for a given class (override). |
See Reference for the exhaustive list and the mp.openapi.servers.path.<path> / mp.openapi.servers.operation.<operationId> variants.
Differences from OpenAPI 3.0 (reminder)
OpenAPI 3.1 (served by MP OpenAPI 4.2) fully aligns with JSON Schema 2020-12: type may be an array (["string", "null"]), nullable is replaced by that syntax, examples is an array, webhooks is added at the root. Grimm reflects these choices in its serializer.
Further reading
-
Internals — detailed pipeline, Vauban BCE, threading.
-
Reference — annotations,
mp.openapi.*keys, artefacts. -
Usage patterns — full examples.