Skip to content

Commit 5661d71

Browse files
committed
Expand type guidance and optional further inspection
Provide examples of narrowing multiple types, and make it clear that every schema without a `type` keyword allows all types. Also note that implementations MAY go beyond these requirements, but set boundaries on what they can do.
1 parent 9fb9893 commit 5661d71

File tree

1 file changed

+32
-6
lines changed

1 file changed

+32
-6
lines changed

src/oas.md

Lines changed: 32 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -301,7 +301,7 @@ API data has three forms:
301301
##### JSON Data
302302

303303
JSON-serialized data is nearly equivalent to the data form because the [JSON Schema data model](https://www.ietf.org/archive/id/draft-bhutton-json-schema-01.html#section-4.2.1) is nearly equivalent to the JSON representation.
304-
The serialized UTF-8 JSON string `{"when": "1985-04-12T23%3A20%3A50.52"}` represents an object with one data field, named `when`, with a string value, `1985-04-12T23%3A20%3A50.52`.
304+
The serialized UTF-8 JSON string `{"when": "1985-04-12T23:20:50.52"}` represents an object with one data field, named `when`, with a string value, `1985-04-12T23:20:50.52`.
305305

306306
The exact application form is beyond the scope of this specification, as can be shown with the following schema for our JSON instance:
307307

@@ -328,10 +328,33 @@ Serializing data into such formats requires either examining the schema-validate
328328

329329
When inspecting schemas, given a starting point schema, implementations MUST examine that schema and all schemas that can be reached from it by following only `$ref` and `allOf` keywords.
330330
These schemas are guaranteed to apply to any instance.
331+
When searching schemas for `type`, if the `type` keyword's value is a list of types and the serialized value can be successfully parsed as more than one of the types in the list, and no other findable `type` keyword disambiguates the actual required type, the behavior is implementation-defined.
332+
Schema Objects that do not contain `type` MUST be considered to allow all types, regardless of which other keywords are present (e.g. `maximum` applies to numbers, but _does not_ require the instance to be a number).
331333

332-
Due to this limited requirement for searching schemas, serializers that have access to validated data MUST inspect the data if possible; implementations that either do not work with runtime data (such as code generators) or cannot access validated data for some reason MUST fall back to schema inspection.
334+
Implementations MAY inspect subschemas or possible reference targets of other keywords such as `oneOf` or `$dynamicRef`, but MUST NOT attempt to resolve ambiguities.
335+
For example, if an implementation opts to inspect `anyOf`, the schema:
333336

334-
When searching schemas for `type`, if the `type` keyword's value is a list of types and the serialized value can be successfully parsed as more than one of the types in the list, the behavior is implementation-defined.
337+
```yaml
338+
anyOf:
339+
- type: number
340+
minimum: 0
341+
- type: number
342+
maximum: 100
343+
```
344+
345+
unambiguously indicates a numeric type, but the schema:
346+
347+
```yaml
348+
anyOf:
349+
- type: number
350+
- maximum: 100
351+
```
352+
353+
does not, because the second subschema allows all types.
354+
355+
Due to these limited requirements for searching schemas, serializers that have access to validated data MUST inspect the data if possible; implementations that either do not work with runtime data (such as code generators) or cannot access validated data for some reason MUST fall back to schema inspection.
356+
357+
Recall also that in JSON Schema, keywords that apply to a specific type (e.g. `pattern` applies to strings, `minimum` applies to numbers) _do not_ require or imply that the data will actually be of that type.
335358

336359
As an example of these processes, given these OpenAPI components:
337360

@@ -352,8 +375,9 @@ components:
352375
properties:
353376
code:
354377
allOf:
355-
- type: string
378+
- type: [string, number]
356379
pattern: "1"
380+
minimum: 0
357381
- type: string
358382
pattern: "2"
359383
count:
@@ -373,12 +397,14 @@ We must first search the schema for `properties` or other property-defining keyw
373397
* `#/components/requestBodies/Form/content/application~1x-www-form-urlencoded/schema` (initial starting point schema, only `$ref`)
374398
* `#/components/schemas/FormData` (follow `$ref`, found `properties`)
375399
* `#/components/schemas/FormData/properties/code` (starting point schema for `code` property)
376-
* `#/components/schemas/FormData/properties/code/allOf/0` (follow `allOf`, but no `type`)
400+
* `#/components/schemas/FormData/properties/code/allOf/0` (follow `allOf`, found `type: [string, number]`)
377401
* `#/components/schemas/FormData/properties/code/allOf/1` (follow `allOf`, found `type: string`)
378402
* `#/components/schemas/FormData/properties/count` (starting point schema for `count` property, found `type: integer`)
379403
* `#/components/schemas/FormData/properties/extra` (starting point schema for `extra` property, found `type: object`)
380404

381-
From this, we determine that `code` is a string that happens to look like a number, while `count` needs to be parsed into a number _prior_ to schema validation.
405+
Note that for `code` we first found an ambiguous `type`, but then found another `type` keyword that ensures only one of the two possibilities is valid.
406+
407+
From this inspection, we determine that `code` is a string that happens to look like a number, while `count` needs to be parsed into a number _prior_ to schema validation.
382408
Furthermore, the `extra` string is in fact an XML serialization of an object containing an `info` property.
383409
This means that the data form of this serialization is equivalent to the following JSON object:
384410

0 commit comments

Comments
 (0)