跳至內容

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 }

找不到您要找的內容嗎? 向社群提問 發現錯誤? 告訴我們