Annotation mapping
It is possible to add additional annotations to a source type
. Currently, this is available as
-
global annotation type mapping:
it adds an annotation to the model class generated for the
source type
. -
global & endpoint parameter annotation type mapping:
it adds an annotation to a parameter of the
source type
(this includes request body parameters).
The global annotation mapping should be added to the map/types
or map/parameters
section in the mapping.yaml.
The endpoint (http method) mapping restricts the mapping to a specific endpoint. This will go to the map/paths/<endpoint path>/parameters
section in the mapping.yaml.
The annotation type mapping is similar to other mappings and is defined like this:
type: {source type} @ {annotation type}
-
type is required.
-
{source type} is the type name used in the OpenAPI description and names the type that should receive the additional annotation.
-
{annotation type} is the fully qualified class name of the java annotation type. It may have parameters (see example below).
-
The samples project has a small example using annotation mappings similar to the one described below.
mapping example
Given the following OpenAPI description, that describe two (echo like) endpoints that receive an object via post and return the same object. In the mapping file we add a custom bean validation annotation. It checks the sum of both properties in Foo
and Bar
.
openapi: 3.1.0
info:
title: openapi-processor-spring sample api
version: 1.0.0
paths:
/foo:
post:
tags:
- foo
summary: annotation mapping example.
description: a simple endpoint where an annotation mapping is used on the request body
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/Foo'
required: true
responses:
'200':
description: echo of the source parameter
content:
application/json:
schema:
$ref: '#/components/schemas/Foo'
/bar:
post:
tags:
- bar
summary: annotation mapping example.
description: a simple endpoint where an annotation mapping is used on the request body
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/Bar'
required: true
responses:
'200':
description: echo of the source parameter
content:
application/json:
schema:
$ref: '#/components/schemas/Bar'
components:
schemas:
Foo:
type: object
properties:
foo1:
type: integer
minimum: 0
foo2:
type: integer
minimum: -10
Bar:
type: object
properties:
bar1:
type: integer
bar2:
type: integer
and a mapping.yaml
with annotation type mappings:
openapi-processor-mapping: v2.1 (1)
options:
package-name: io.openapiprocessor.openapi
javadoc: true
format-code: true
bean-validation: true
map:
types:
- type: Bar @ io.openapiprocessor.samples.validations.Sum(24) (2)
parameters:
- type: Foo @ io.openapiprocessor.samples.validations.Sum(value = 42) (3)
# this formats do work too (4)
# - type: Foo @ annotation.Bar
# - type: Foo @ annotation.Bar()
# - type: Foo @ annotation.Bar("bar")
# - type: Foo @ annotation.Bar(value = "bar", foo = 2)
The Sum
annotation in the example is a custom bean validation but the feature itself is not limited to bean validation.
1 | use v2.1 as the mapping version to avoid validation warnings in the mapping file. |
2 | the Bar mapping is using a global type annotation mapping, so the annotation is added to the generated Bar class. |
3 | the Foo mapping adds the annotation to the parameter of the endpoint methods that use Foo . |
4 | this is a list of examples that shows annotation parameters. |
Here are the generated interfaces, first the FooApi
:
package io.openapiprocessor.openapi.api;
import io.openapiprocessor.openapi.model.Foo;
import io.openapiprocessor.samples.validations.Sum;
import javax.validation.Valid;
import javax.validation.constraints.NotNull;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
public interface FooApi {
/**
* annotation mapping example.
*
* <p>a simple endpoint where an annotation mapping is used on the request body
*
* @return echo of the source parameter
*/
@PostMapping(
path = "/foo",
consumes = {"application/json"},
produces = {"application/json"})
Foo postFoo(@RequestBody @Sum(value = 42) @Valid @NotNull Foo body); (1)
}
1 | here is the additional annotation. |
and the BarApi
and the Bar
class:
package io.openapiprocessor.openapi.api;
import io.openapiprocessor.openapi.model.Bar;
import javax.validation.Valid;
import javax.validation.constraints.NotNull;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
public interface BarApi {
/**
* annotation mapping example.
*
* <p>a simple endpoint where an annotation mapping is used on the request body
*
* @return echo of the source parameter
*/
@PostMapping(
path = "/bar",
consumes = {"application/json"},
produces = {"application/json"})
Bar postBar(@RequestBody @Valid @NotNull Bar body); (1)
}
1 | no annotation here, mapping says it should be on the class: |
package io.openapiprocessor.openapi.model;
import com.fasterxml.jackson.annotation.JsonProperty;
import io.openapiprocessor.samples.validations.Sum;
@Sum(24) (1)
public class Bar {
@JsonProperty("bar1")
private Integer bar1;
@JsonProperty("bar2")
private Integer bar2;
public Integer getBar1() {
return bar1;
}
public void setBar1(Integer bar1) {
this.bar1 = bar1;
}
public Integer getBar2() {
return bar2;
}
public void setBar2(Integer bar2) {
this.bar2 = bar2;
}
}
1 | and here it is :-) |