跳到内容

oneOf, anyOf, allOf, not

OpenAPI 3.0 提供了几个关键字,您可以使用它们来组合模式。您可以使用这些关键字来创建复杂的模式,或针对多个条件验证值。

  • oneOf – 针对恰好一个子模式验证值
  • allOf – 针对所有子模式验证值
  • anyOf – 针对任何(一个或多个)子模式验证值

此外,还有一个 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
{ "bark": true, "hunts": true, "breed": "Husky", "age": 3 }

allOf

OpenAPI 允许您使用 allOf 关键字组合和扩展模型定义。allOf 接受一个对象定义数组,这些定义用于独立验证,但组合在一起构成单个对象。不过,它并不意味着模型之间存在层次结构。为此,您应该包含 discriminator。要符合 allOf,客户端提供的数据必须符合所有给定的子模式。在下面的示例中,allOf 用作将特定情况下使用的模式与通用模式组合的工具。为了更清晰,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 操作更新宠物项所需的所有信息。它要求用户指定应更新的项的类型,并根据他们的选择针对指定的模式进行验证。请注意,内联或引用的模式必须是模式对象,而不是标准的 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
7
{
8
"pet_type": "Cat",
9
"bark": true # The `Cat` schema does not have the `bark` property
10
}

anyOf

使用 anyOf 关键字来验证数据是否符合给定子模式中的任何数量的模式。也就是说,数据可能同时对一个或多个子模式有效。

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 精确匹配一个子模式,而 anyOf 可以匹配一个或多个子模式。为了更好地理解差异,请使用上面的 示例,但将 anyOf 替换为 oneOf。当使用 oneOf 时,以下请求体是无效的,因为它匹配两个模式而不仅仅是一个

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 }

没有找到您要找的内容? 向社区提问 发现错误? 请告知我们