跳过内容

oneOf, anyOf, allOf, not

OpenAPI 3.0 提供了几个关键词,您可以使用它们来组合 Schema。您可以使用这些关键词创建复杂的 Schema,或根据多个条件验证值。

  • oneOf – 针对子 Schema 中的正好一个验证值
  • allOf – 针对所有子 Schema 验证值
  • anyOf – 针对子 Schema 中的任意一个(或多个)验证值

除了这些,还有一个 not 关键词,您可以使用它来确保值符合指定的 Schema。

oneOf

使用 oneOf 关键词来确保给定数据符合指定 Schema 中的一个。

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) 中验证请求体。您可以根据对象类型,使用它来验证请求体是否包含有关要更新对象的所有必要信息。请注意,内联或引用的 Schema 必须是Schema 对象,而不是标准的 JSON Schema。现在,进行验证。以下 JSON 对象符合其中一个 Schema,因此请求体是正确

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

以下 JSON 对象不符合两个 Schema,因此请求体是不正确

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

以下 JSON 对象同时符合两个 Schema,因此请求体是不正确的——因为它应该只符合其中一个 Schema,因为我们使用了 oneOf 关键词。

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

allOf

OpenAPI 允许您使用 allOf 关键词组合和扩展模型定义。allOf 接受一个对象定义数组,这些定义用于独立验证,但共同构成一个单一对象。然而,它并不意味着模型之间存在层次结构。为此,您应该包含 discriminator。要符合 allOf,客户端提供的数据必须符合所有给定的子 Schema。在以下示例中,allOf 作为一种工具,将特定情况下使用的 Schema 与通用 Schema 结合起来。为了更清晰,oneOf 也与 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

如您所见,此示例验证请求体内容,以确保它包含使用 PUT 操作更新宠物项所需的所有信息。它要求用户指定要更新的项的类型,并根据其选择针对指定的 Schema 进行验证。请注意,内联或引用的 Schema 必须是Schema 对象,而不是标准的 JSON Schema。对于该示例,以下所有请求体都是有效

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 关键词来根据给定子 Schema 中的任意数量进行数据验证。也就是说,数据可以同时符合一个或多个子 Schema。

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

请注意,内联或引用的 Schema 必须是Schema 对象,而不是标准的 JSON Schema。在此示例中,以下 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
}

以下示例无效,因为它不包含这两个 Schema 所需的任何属性

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

anyOf 与 oneOf 之间的区别

oneOf 匹配正好一个子 Schema,而 anyOf 可以匹配一个或多个子 Schema。为了更好地理解这种区别,请使用上面的示例,但将 anyOf 替换为 oneOf。当使用 oneOf 时,以下请求体是无效的,因为它同时匹配两个 Schema 而不仅仅是一个

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

not

not 关键词并非严格意义上的 Schema 组合,但它与上面提到的所有关键词一样,有助于您修改 Schema 并使其更具体。

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 }

没有找到您想要的内容?询问社区 发现错误?请告诉我们

© . All rights reserved.