Skip to content

Commit 2077b65

Browse files
committed
one-of-interface docs
1 parent 06e4ec3 commit 2077b65

3 files changed

Lines changed: 108 additions & 1 deletion

File tree

docs/modules/ROOT/nav.adoc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
** xref:processor/parameter.adoc[Parameter]
88
** xref:processor/requestbody.adoc[Request Body]
99
** xref:processor/response.adoc[Responses]
10+
** xref:processor/one-of-interface.adoc[oneOf]
1011
** xref:processor/deprecated.adoc[Deprecated]
1112
** xref:processor/identifier.adoc[Identifier]
1213
* xref:mapping/index.adoc[Type Mapping]

docs/modules/ROOT/pages/processor/configuration.adoc

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ openapi-processor-mapping: v2
1313
options:
1414
package-name: io.openapiprocessor.sample
1515
model-name-suffix: Resource
16+
one-of-interface: true
1617
bean-validation: true
1718
format-code: false
1819
javadoc: true
@@ -33,7 +34,7 @@ Interfaces and models will be generated into the `api` and `model` subpackages o
3334
** so the final package name of the generated interfaces will be `"$\{package-name\}.api"`,
3435
** and the final package name of the generated models will be `"$\{package-name\}.model"`
3536

36-
* `model-suffix-name` (**optional**, default is empty).See xref:_model_name_suffix[below].
37+
* `model-suffix-name` (**optional**, default is empty). See xref:_model_name_suffix[below].
3738

3839
* `bean-validation` (**optional**, `true` or `false`) enables generation of bean validation
3940
annotations. Default is `false`. See link:{bean-validation}[Bean Validation Specification, window="_blank"].
@@ -42,6 +43,8 @@ annotations. Default is `false`. See link:{bean-validation}[Bean Validation Spec
4243

4344
* `format-code` (**optional**, `true` or `false`) enable or disable the code formatter: Default is `true`.
4445

46+
* `one-of-interface` (**optional**, `true` or `false`) enables generation of marker interfaces for `oneOf` objects. See xref:processor/one-of-interface.adoc#_marker_interfaces[oneOf marker interfaces].
47+
4548
[#_model_name_suffix]
4649
=== model name suffix:
4750

@@ -134,6 +137,10 @@ public class BarResource { // <4>
134137
<3> the class name of the `Foo` schema got the configured `Resource` suffix
135138
<4> the class name of the `BarResource` is identical to the original schema name. Since the existing suffix is equal to `model-name-suffix` it is ignored. Otherwise, This prevents funny class names like `BarResourceResource`.
136139

140+
141+
142+
143+
137144
== map:
138145

139146
Using type mapping we can tell the processor to map types (schemas) from an `openapi.yaml`
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
= oneOf
2+
3+
Generating model classes from an `oneOf` has the challenge to handle a number of usually unrelated objects with different properties.
4+
5+
Java has no way to define a class member that can have multiple unrelated types (e.g. it can be of class `Foo` or class `Bar`), except using `Object`.
6+
7+
This is the default behavior of the processor.
8+
9+
The problem with `Object` is that it doesn't provide any information at all. You have to know (from the OpenAPI) what that `Object` could be.
10+
11+
To improve usability the processor is able to generate marker interfaces to provide a bit more information than `Object`.
12+
13+
[#_marker_interfaces]
14+
== marker interfaces
15+
16+
[.badge .badge-since]+since 2022.3+
17+
18+
Generation of marker interfaces is enabled by setting the `one-of-interface` option to `true` (See xref:processor/configuration.adoc[configuration]). For backward compatibility it is `false` by default.
19+
20+
[source,yaml]
21+
----
22+
openapi-processor-mapping: v2
23+
24+
options:
25+
one-of-interface: true
26+
----
27+
28+
The processor will now create a marker interface for a `oneOf` of `object` s that is implemented by all `object` s in the `oneOf` list.
29+
30+
Here is an example. The response is an object `Foo` with a `foo` property that can have the type `Foo` or `Bar`.
31+
32+
[source,yaml]
33+
----
34+
openapi: 3.0.3
35+
info:
36+
title: oneOf marker interface
37+
version: 1.0.0
38+
39+
paths:
40+
/foo:
41+
get:
42+
responses:
43+
'200':
44+
description: oneOf
45+
content:
46+
application/json:
47+
schema:
48+
$ref: '#/components/schemas/Foo'
49+
50+
components:
51+
schemas:
52+
53+
Foo:
54+
type: object
55+
properties:
56+
foo:
57+
$ref: '#/components/schemas/FooOneOf'
58+
59+
FooOneOf:
60+
oneOf:
61+
- $ref: '#/components/schemas/Foo'
62+
- $ref: '#/components/schemas/Bar'
63+
64+
# omitted description of Foo & Bar
65+
----
66+
67+
The processor generates the class `Foo` as
68+
69+
[source,java]
70+
----
71+
// simplified
72+
public class Foo {
73+
private FooOneOf foo;
74+
}
75+
----
76+
77+
with the type `FooOneOf` instead of `Object`. `FooOneOf` is the marker interface:
78+
79+
[source,java]
80+
----
81+
public interface FooOneOf {}
82+
----
83+
84+
The two model classes `Foo` & `Bar` implement the marker interface:
85+
86+
[source,java]
87+
----
88+
// simplified
89+
public class Foo implements FooOneOf { /* ... */ }
90+
----
91+
92+
[source,java]
93+
----
94+
// simplified
95+
public class Bar implements FooOneOf { /* ... */ }
96+
----
97+
98+
Which is better than having `foo` just as `Object`. The marker interface helps to find the possible types of `foo`.
99+

0 commit comments

Comments
 (0)