コンテンツにスキップ

oneOf、anyOf、allOf、not

OpenAPI 3.0 では、スキーマを結合するために使用できるいくつかのキーワードが提供されています。これらのキーワードを使用して、複雑なスキーマを作成したり、複数の基準に対して値を検証したりできます。

  • oneOf – サブスキーマの いずれか 1 つのみ に対して値を検証します
  • allOf – サブスキーマの すべて に対して値を検証します
  • anyOf – サブスキーマの いずれか (1 つまたは複数) に対して値を検証します

これら以外に、指定されたスキーマに対して値が 無効 であることを確認するために使用できる not キーワードがあります。

oneOf

oneOf キーワードを使用して、指定されたスキーマのいずれかに対して与えられたデータが有効であることを確認します。

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

上記の例は、「更新」操作 (PATCH) でリクエストボディを検証する方法を示しています。オブジェクトの種類に応じて、更新されるオブジェクトに関する必要な情報がすべてリクエストボディに含まれているかを検証するために使用できます。インラインまたは参照されるスキーマは、標準の JSON スキーマではなく、スキーマオブジェクト である必要があります。次に、検証についてです。次の JSON オブジェクトは、いずれかのスキーマに対して 有効 であるため、リクエストボディは 正しい です。

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

次の JSON オブジェクトは、両方のスキーマに対して 無効 であるため、リクエストボディは 正しくありません

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

次の JSON オブジェクトは、両方 のスキーマに対して 有効 であるため、リクエストボディは 正しくありませんoneOf キーワードを使用しているため、スキーマのいずれか 1 つのみに対して有効である必要があります。

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

allOf

OpenAPI では、allOf キーワードを使用してモデル定義を結合および拡張できます。allOf は、独立した検証に使用されるが、まとめて単一のオブジェクトを構成するオブジェクト定義の配列を受け取ります。それでも、モデル間の階層を意味するわけではありません。その目的のために、discriminator を含める必要があります。allOf に対して有効であるためには、クライアントによって提供されるデータは、与えられたすべてのサブスキーマに対して有効である必要があります。次の例では、allOf は、一般的なスキーマと特定のケースで使用されるスキーマを結合するためのツールとして機能します。より明確にするために、oneOfdiscriminator とともに使用されています。

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

ご覧のとおり、この例では、PUT 操作でペットアイテムを更新するために必要なすべての情報がリクエストボディのコンテンツに含まれていることを検証します。ユーザーは、更新するアイテムの種類を指定する必要があり、選択に応じて指定されたスキーマに対して検証します。インラインまたは参照されるスキーマは、標準の JSON スキーマではなく、スキーマオブジェクト である必要があります。この例では、以下のすべてのリクエストボディが 有効 です。

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
}

以下のリクエストボディは 無効 です。

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

anyOf

anyOf キーワードを使用して、与えられたサブスキーマの任意の数に対してデータを検証します。つまり、データは同時に1つまたは複数のサブスキーマに対して有効である場合があります。

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

インラインまたは参照されるスキーマは、標準の JSON スキーマではなく、スキーマオブジェクト である必要があります。この例では、以下の JSON リクエストボディは 有効 です。

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
}

次の例は、両方のスキーマに必要なプロパティが何も含まれていないため、無効 です。

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

anyOf と oneOf の違い

oneOf は厳密に 1 つのサブスキーマと一致し、anyOf は 1 つ以上のサブスキーマと一致します。違いをよりよく理解するには、anyOfoneOf に置き換えて 上記の 例を使用してください。oneOf を使用すると、次のリクエストボディは、1 つだけではなく両方のスキーマと一致するため、無効 です。

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

not

not キーワードは厳密にはスキーマを結合するものではありませんが、上記のすべてのキーワードと同様に、スキーマを修正してより具体的にするのに役立ちます。

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

この例では、ユーザーは整数以外の任意の種類の pet_type 値を指定する必要があります(つまり、配列、ブール値、数値、オブジェクト、または文字列である必要があります)。次のリクエストボディは 有効 です。

1
{ "pet_type": "Cat" }

そして、次が 無効 です。

1
{ "pet_type": 11 }

お探しのものが見つかりませんでしたか?コミュニティに尋ねる間違いを見つけましたか?お知らせください