oneOf、anyOf、allOf、not
OpenAPI 3.0 では、スキーマを結合するために使用できるいくつかのキーワードが提供されています。これらのキーワードを使用して、複雑なスキーマを作成したり、複数の基準に対して値を検証したりできます。
oneOf
– サブスキーマの いずれか 1 つのみ に対して値を検証しますallOf
– サブスキーマの すべて に対して値を検証しますanyOf
– サブスキーマの いずれか (1 つまたは複数) に対して値を検証します
これら以外に、指定されたスキーマに対して値が 無効 であることを確認するために使用できる not
キーワードがあります。
oneOf
oneOf
キーワードを使用して、指定されたスキーマのいずれかに対して与えられたデータが有効であることを確認します。
1paths: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: Updated14
15components:16 schemas:17 Dog:18 type: object19 properties:20 bark:21 type: boolean22 breed:23 type: string24 enum: [Dingo, Husky, Retriever, Shepherd]25 Cat:26 type: object27 properties:28 hunts:29 type: boolean30 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
は、一般的なスキーマと特定のケースで使用されるスキーマを結合するためのツールとして機能します。より明確にするために、oneOf
も discriminator
とともに使用されています。
1paths: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_type13 responses:14 "200":15 description: Updated16
17components:18 schemas:19 Pet:20 type: object21 required:22 - pet_type23 properties:24 pet_type:25 type: string26 discriminator:27 propertyName: pet_type28
29 Dog: # "Dog" is a value for the pet_type property (the discriminator value)30 allOf: # Combines the main `Pet` schema with `Dog`-specific properties31 - $ref: "#/components/schemas/Pet"32 - type: object33 # all other properties specific to a `Dog`34 properties:35 bark:36 type: boolean37 breed:38 type: string39 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 properties43 - $ref: "#/components/schemas/Pet"44 - type: object45 # all other properties specific to a `Cat`46 properties:47 hunts:48 type: boolean49 age:50 type: integer
ご覧のとおり、この例では、PUT 操作でペットアイテムを更新するために必要なすべての情報がリクエストボディのコンテンツに含まれていることを検証します。ユーザーは、更新するアイテムの種類を指定する必要があり、選択に応じて指定されたスキーマに対して検証します。インラインまたは参照されるスキーマは、標準の JSON スキーマではなく、スキーマオブジェクト である必要があります。この例では、以下のすべてのリクエストボディが 有効 です。
1{2 "pet_type": "Cat",3 "age": 34}5
6{7 "pet_type": "Dog",8 "bark": true9}10
11{12 "pet_type": "Dog",13 "bark": false,14 "breed": "Dingo"15}
以下のリクエストボディは 無効 です。
1{2 "age": 3 # Does not include the pet_type property3}4
5{6 "pet_type": "Cat",7 "bark": true # The `Cat` schema does not have the `bark` property8}
anyOf
anyOf
キーワードを使用して、与えられたサブスキーマの任意の数に対してデータを検証します。つまり、データは同時に1つまたは複数のサブスキーマに対して有効である場合があります。
1paths: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: Updated14
15components:16 schemas:17 PetByAge:18 type: object19 properties:20 age:21 type: integer22 nickname:23 type: string24 required:25 - age26
27 PetByType:28 type: object29 properties:30 pet_type:31 type: string32 enum: [Cat, Dog]33 hunts:34 type: boolean35 required:36 - pet_type
インラインまたは参照されるスキーマは、標準の JSON スキーマではなく、スキーマオブジェクト である必要があります。この例では、以下の JSON リクエストボディは 有効 です。
1{2 "age": 13}4
5{6 "pet_type": "Cat",7 "hunts": true8}9
10{11 "nickname": "Fido",12 "pet_type": "Dog",13 "age": 414}
次の例は、両方のスキーマに必要なプロパティが何も含まれていないため、無効 です。
1{ "nickname": "Mr. Paws", "hunts": false }
anyOf と oneOf の違い
oneOf
は厳密に 1 つのサブスキーマと一致し、anyOf
は 1 つ以上のサブスキーマと一致します。違いをよりよく理解するには、anyOf
を oneOf
に置き換えて 上記の 例を使用してください。oneOf
を使用すると、次のリクエストボディは、1 つだけではなく両方のスキーマと一致するため、無効 です。
1{ "nickname": "Fido", "pet_type": "Dog", "age": 4 }
not
not
キーワードは厳密にはスキーマを結合するものではありませんが、上記のすべてのキーワードと同様に、スキーマを修正してより具体的にするのに役立ちます。
1paths:2 /pets:3 patch:4 requestBody:5 content:6 application/json:7 schema:8 $ref: "#/components/schemas/PetByType"9 responses:10 "200":11 description: Updated12
13components:14 schemas:15 PetByType:16 type: object17 properties:18 pet_type:19 not:20 type: integer21 required:22 - pet_type
この例では、ユーザーは整数以外の任意の種類の pet_type
値を指定する必要があります(つまり、配列、ブール値、数値、オブジェクト、または文字列である必要があります)。次のリクエストボディは 有効 です。
1{ "pet_type": "Cat" }
そして、次が 無効 です。
1{ "pet_type": 11 }
お探しのものが見つかりませんでしたか?コミュニティに尋ねる間違いを見つけましたか?お知らせください