Skip to content

oneOf, anyOf, allOf, not

OpenAPI 3.0 provides several keywords which you can use to combine schemas. You can use these keywords to create a complex schema, or validate a value against multiple criteria.

  • oneOf – validates the value against exactly one of the subschemas
  • allOf – validates the value against all the subschemas
  • anyOf – validates the value against any (one or more) of the subschemas

Besides these, there is a not keyword which you can use to make sure the value is not valid against the specified schema.

oneOf

Use the oneOf keyword to ensure the given data is valid against one of the specified schemas.

1
paths:
2
/pets:
3
patch:
4
requestBody:
5
content:
6
application/json:
7
schema:
8
oneOf:
9
- $ref: "#/components/schemas/Cat"
10
- $ref: "#/components/schemas/Dog"
11
responses:
12
"200":
13
description: Updated
14
15
components:
16
schemas:
17
Dog:
18
type: object
19
properties:
20
bark:
21
type: boolean
22
breed:
23
type: string
24
enum: [Dingo, Husky, Retriever, Shepherd]
25
Cat:
26
type: object
27
properties:
28
hunts:
29
type: boolean
30
age:
31
type: integer

The example above shows how to validate the request body in the “update” operation (PATCH). You can use it to validate the request body contains all the necessary information about the object to be updated, depending on the object type. Note the inline or referenced schema must be a schema object, not a standard JSON Schema. Now, to validation. The following JSON object is valid against one of the schemas, so the request body is correct:

1
{ "bark": true, "breed": "Dingo" }

The following JSON object is not valid against both schemas, so the request body is incorrect:

1
{ "bark": true, "hunts": true }

The following JSON object is valid against both schemas, so the request body is incorrect – it should be valid against only one of the schemas, since we are using the oneOf keyword.

1
{ "bark": true, "hunts": true, "breed": "Husky", "age": 3 }

allOf

OpenAPI lets you combine and extend model definitions using the allOf keyword. allOf takes an array of object definitions that are used for independent validation but together compose a single object. Still, it does not imply a hierarchy between the models. For that purpose, you should include the discriminator. To be valid against allOf, the data provided by the client must be valid against all of the given subschemas. In the following example, allOf acts as a tool for combining schemas used in specific cases with the general one. For more clearness, oneOf is also used with a discriminator.

1
paths:
2
/pets:
3
patch:
4
requestBody:
5
content:
6
application/json:
7
schema:
8
oneOf:
9
- $ref: "#/components/schemas/Cat"
10
- $ref: "#/components/schemas/Dog"
11
discriminator:
12
propertyName: pet_type
13
responses:
14
"200":
15
description: Updated
16
17
components:
18
schemas:
19
Pet:
20
type: object
21
required:
22
- pet_type
23
properties:
24
pet_type:
25
type: string
26
discriminator:
27
propertyName: pet_type
28
29
Dog: # "Dog" is a value for the pet_type property (the discriminator value)
30
allOf: # Combines the main `Pet` schema with `Dog`-specific properties
31
- $ref: "#/components/schemas/Pet"
32
- type: object
33
# all other properties specific to a `Dog`
34
properties:
35
bark:
36
type: boolean
37
breed:
38
type: string
39
enum: [Dingo, Husky, Retriever, Shepherd]
40
41
Cat: # "Cat" is a value for the pet_type property (the discriminator value)
42
allOf: # Combines the main `Pet` schema with `Cat`-specific properties
43
- $ref: "#/components/schemas/Pet"
44
- type: object
45
# all other properties specific to a `Cat`
46
properties:
47
hunts:
48
type: boolean
49
age:
50
type: integer

As you can see, this example validates the request body content to make sure it includes all the information needed to update a pet item with the PUT operation. It requires user to specify which type of the item should be updated, and validates against the specified schema according to their choice. Note the inline or referenced schema must be a schema object, not a standard JSON schema. For that example, all of the following request bodies are valid:

1
{
2
"pet_type": "Cat",
3
"age": 3
4
}
5
6
{
7
"pet_type": "Dog",
8
"bark": true
9
}
10
11
{
12
"pet_type": "Dog",
13
"bark": false,
14
"breed": "Dingo"
15
}

The following request bodies are not valid:

1
{
2
"age": 3 # Does not include the pet_type property
3
}
4
5
6
7
{
8
"pet_type": "Cat",
9
"bark": true # The `Cat` schema does not have the `bark` property
10
}

anyOf

Use the anyOf keyword to validate the data against any amount of the given subschemas. That is, the data may be valid against one or more subschemas at the same time.

1
paths:
2
/pets:
3
patch:
4
requestBody:
5
content:
6
application/json:
7
schema:
8
anyOf:
9
- $ref: "#/components/schemas/PetByAge"
10
- $ref: "#/components/schemas/PetByType"
11
responses:
12
"200":
13
description: Updated
14
15
components:
16
schemas:
17
PetByAge:
18
type: object
19
properties:
20
age:
21
type: integer
22
nickname:
23
type: string
24
required:
25
- age
26
27
PetByType:
28
type: object
29
properties:
30
pet_type:
31
type: string
32
enum: [Cat, Dog]
33
hunts:
34
type: boolean
35
required:
36
- pet_type

Note the inline or referenced schema must be a schema object, not a standard JSON schema. With this example, the following JSON request bodies are valid:

1
{
2
"age": 1
3
}
4
5
{
6
"pet_type": "Cat",
7
"hunts": true
8
}
9
10
{
11
"nickname": "Fido",
12
"pet_type": "Dog",
13
"age": 4
14
}

The following example is not valid, because it does not contain any of the required properties for both of the schemas:

1
{ "nickname": "Mr. Paws", "hunts": false }

Difference Between anyOf and oneOf

oneOf matches exactly one subschema, and anyOf can match one or more subschemas. To better understand the difference, use the example above but replace anyOf with oneOf. When using oneOf, the following request body is not valid because it matches both schemas and not just one:

1
{ "nickname": "Fido", "pet_type": "Dog", "age": 4 }

not

The not keyword does not exactly combine schemas, but as all of the keywords mentioned above it helps you to modify your schemas and make them more specific.

1
paths:
2
/pets:
3
patch:
4
requestBody:
5
content:
6
application/json:
7
schema:
8
$ref: "#/components/schemas/PetByType"
9
responses:
10
"200":
11
description: Updated
12
13
components:
14
schemas:
15
PetByType:
16
type: object
17
properties:
18
pet_type:
19
not:
20
type: integer
21
required:
22
- pet_type

In this example, user should specify the pet_type value of any type except integer (that is, it should be an array, boolean, number, object, or string). The following request body is valid:

1
{ "pet_type": "Cat" }

And the following is not valid:

1
{ "pet_type": 11 }

Did not find what you were looking for? Ask the community Found a mistake? Let us know