Skip to content

Commit dfd63aa

Browse files
authored
Added documentation for #390 (#394)
1 parent b4f43ab commit dfd63aa

File tree

1 file changed

+191
-0
lines changed

1 file changed

+191
-0
lines changed

doc/openapi-discriminators.md

Lines changed: 191 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,191 @@
1+
[//]: # (Copyright 2021, Oracle and/or its affiliates.)
2+
3+
## OpenAPI 3.x discriminator support
4+
5+
Starting with `1.0.51`, `json-schema-validator` partly supports the use of discriminators as described under
6+
https://github.com/OAI/OpenAPI-Specification/blame/master/versions/3.0.3.md#L2693 and following.
7+
8+
## How to use
9+
10+
1. Configure `SchemaValidatorsConfig` accordingly:
11+
```java
12+
class Demo{
13+
void demo() {
14+
SchemaValidatorsConfig config = new SchemaValidatorsConfig();
15+
config.setOpenAPI3StyleDiscriminators(true); // defaults to false
16+
}
17+
}
18+
```
19+
2. Use the configured `SchemaValidatorsConfig` with the `JSONSchemaFactory` when creating the `JSONSchema`
20+
```java
21+
class Demo{
22+
void demo() {
23+
SchemaValidatorsConfig config = new SchemaValidatorsConfig();
24+
config.setOpenAPI3StyleDiscriminators(true); // defaults to false
25+
JsonSchema schema = validatorFactory.getSchema(schemaURI, schemaJacksonJsonNode, config);
26+
}
27+
}
28+
```
29+
3. Ensure that the type field that you want to use as discriminator `propertyName` is required in your schema
30+
31+
## Scope of Support
32+
33+
Discriminators are unfortunately somewhat vague in their definition, especially in regard to JSON Schema validation. So, only
34+
those parts that are indisputable are considered at this moment.
35+
36+
### Supported:
37+
38+
* Polymorphism using `allOf` and `anyOf` with implicit and explicit `mapping`
39+
* `discriminator` on base types and types derived
40+
thereof `A(with base discriminator) -> B(with optional additive discriminator) -> C(with optional additive discriminator)`
41+
42+
### Not supported:
43+
44+
* `propertyName` redefinition is prohibited on additive discriminators
45+
* `mapping` key redefinition is also prohibited on additive discriminators
46+
* `oneOf` ignores discriminators as today it is not clear from the spec whether `oneOf` + `discriminator` should be equal to
47+
`anyOf` + `discriminator` or not. Especially if `oneOf` should respect the discriminator and skip the other schemas, it's
48+
functionally not JSON Schema `oneOf` anymore as multiple matches would not make the validation fail anymore.
49+
* the specification indicates that inline properties should be ignored.
50+
So, this example would respect `foo`
51+
```yaml
52+
allOf:
53+
- $ref: otherSchema
54+
- type: object
55+
properties:
56+
foo:
57+
type: string
58+
required: ["foo"]
59+
```
60+
while
61+
```yaml
62+
properties:
63+
foo:
64+
type: string
65+
required: ["foo"]
66+
allOf:
67+
- $ref: otherSchema
68+
```
69+
should ignore `foo`. **Ignoring `foo` in the second example is currently not implemented**
70+
* You won't get a warning if your `discriminator` uses a field for `propertyName` that is not `required`
71+
72+
## Schema Examples
73+
74+
more examples in https://github.com/networknt/json-schema-validator/blob/master/src/test/resources/openapi3/discriminator.json
75+
76+
### Base type and extended type (the `anyOf` forward references are required)
77+
78+
#### the simplest example:
79+
80+
```json
81+
{
82+
"anyOf": [
83+
{
84+
"$ref": "#/components/schemas/Room"
85+
},
86+
{
87+
"$ref": "#/components/schemas/BedRoom"
88+
}
89+
],
90+
"components": {
91+
"schemas": {
92+
"Room": {
93+
"type": "object",
94+
"properties": {
95+
"@type": {
96+
"type": "string"
97+
},
98+
"floor": {
99+
"type": "integer"
100+
}
101+
},
102+
"required": [
103+
"@type"
104+
],
105+
"discriminator": {
106+
"propertyName": "@type"
107+
}
108+
},
109+
"BedRoom": {
110+
"type": "object",
111+
"allOf": [
112+
{
113+
"$ref": "#/components/schemas/Room"
114+
},
115+
{
116+
"type": "object",
117+
"properties": {
118+
"numberOfBeds": {
119+
"type": "integer"
120+
}
121+
},
122+
"required": [
123+
"numberOfBeds"
124+
]
125+
}
126+
]
127+
}
128+
}
129+
}
130+
}
131+
```
132+
133+
#### Here the default mapping key for `BedRoom` is overridden with `bed` from `Room`
134+
135+
```json
136+
{
137+
"anyOf": [
138+
{
139+
"$ref": "#/components/schemas/Room"
140+
},
141+
{
142+
"$ref": "#/components/schemas/BedRoom"
143+
}
144+
],
145+
"components": {
146+
"schemas": {
147+
"Room": {
148+
"type": "object",
149+
"properties": {
150+
"@type": {
151+
"type": "string"
152+
},
153+
"floor": {
154+
"type": "integer"
155+
}
156+
},
157+
"required": [
158+
"@type"
159+
],
160+
"discriminator": {
161+
"propertyName": "@type",
162+
"mapping": {
163+
"bed": "#/components/schemas/BedRoom"
164+
}
165+
}
166+
},
167+
"BedRoom": {
168+
"type": "object",
169+
"allOf": [
170+
{
171+
"$ref": "#/components/schemas/Room"
172+
},
173+
{
174+
"type": "object",
175+
"properties": {
176+
"numberOfBeds": {
177+
"type": "integer"
178+
}
179+
},
180+
"required": [
181+
"numberOfBeds"
182+
]
183+
}
184+
]
185+
}
186+
}
187+
}
188+
}
189+
```
190+
191+
###

0 commit comments

Comments
 (0)