mapping OpenAPI formats
3.June 2023
Assume we have this simple (but useless ;-) OpenAPI description. It uses a custom integer format
to specify that the integer parameter and response represents a year.
openapi: 3.1
info:
title: pending API
version: 1.0.0
paths:
/query:
get:
description: echo query parameter with type mapping
parameters:
- name: year
description: the year
in: query
required: true
schema:
type: integer (1)
format: year
responses:
'200':
description: echo response
content:
text/plain:
schema:
type: integer (1)
format: year
1 | the integer type with custom format . |
By default, openapi-processor-spring does not know what to do with the custom format and simply maps the OpenAPI integer
to a Java Integer
.
package io.openapiprocessor.oap.api;
import io.openapiprocessor.oap.support.Generated;
import javax.validation.constraints.NotNull;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
@Generated(value = "openapi-processor-spring", version = "2023.2")
public interface Api {
/**
* echo query parameter with type mapping
*
* @return echo response
*/
@GetMapping(
path = "/query",
produces = {"text/plain"})
Integer getQuery(@RequestParam(name = "year") @NotNull Integer year);
}
Since Java has a java.time.Year
class it could be useful to use it instead of Integer
.
We can easily help openapi-processor to generate the interface with java.time.Year
by adding a type mapping to the mapping.yaml
configuration.
openapi-processor-mapping: v3
options:
generated-date: false
package-name: io.openapiprocessor.oap
bean-validation: javax
javadoc: true
map:
types:
- type: integer:year => java.time.Year (1)
1 | this is the interesting part of the mapping.yaml . It tells the processor to map the integer custom format to the java.time.Year class. |
The left side of the arrow is the type
: format
combination used in the OpenAPI and on the right side is the fully qualified java class name that is used in the generated code.
Regenerating the code will now generate the interface like this:
package io.openapiprocessor.oap.api;
import io.openapiprocessor.oap.support.Generated;
import java.time.Year;
import javax.validation.constraints.NotNull;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
@Generated(value = "openapi-processor-spring", version = "2023.2")
public interface Api {
/**
* echo query parameter with type mapping
*
* @return echo response
*/
@GetMapping(
path = "/query",
produces = {"text/plain"})
Year getQuery(@RequestParam(name = "year") @NotNull Year year); (1)
}
1 | it is now using java.time.Year instead of Integer . |
Easy :-)
If such a custom type is used in the properties
of an OpenAPI schema, openapi-processor will use the same type mapping definition.
We can use this simple mechanism for many other types to improve the generated code. Here are a few examples:
- type: string:uuid => java.util.UUID
- type: string:date-time => java.time.Instant
- type: string:offset-date-time => java.time.OffsetDateTime
I’m sure you can find more useful mappings. :-)
summary
This short article described how easy it is to improve the openapi-processor generated code with type mapping.