Last active
June 12, 2019 07:36
-
-
Save handrews/6dfebd56ef97328f9e4dc7a47a1e8bc7 to your computer and use it in GitHub Desktop.
OAS 3.0 JSON Schema from PR #1270 rewritten with JSON Schema draft-08 proposals
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| $id: 'https://openapis.org/schemas/oas/3.0' | |
| $schema: 'http://json-schema.org/draft-08-work-in-progress/schema#' | |
| type: object | |
| required: | |
| - openapi | |
| - info | |
| - paths | |
| allOf: | |
| - $ref: '#/$defs/Mixins/$defs/Extensible' | |
| properties: | |
| openapi: | |
| type: string | |
| pattern: ^3\.0\.\d(-.+)?$ | |
| info: | |
| $ref: '#Info' | |
| externalDocs: | |
| $ref: '#ExternalDocumentation' | |
| servers: | |
| type: array | |
| items: | |
| $ref: '#Server' | |
| security: | |
| type: array | |
| items: | |
| $ref: '#SecurityRequirement' | |
| tags: | |
| type: array | |
| items: | |
| $ref: '#Tag' | |
| paths: | |
| $ref: '#Paths' | |
| components: | |
| $ref: '#Components' | |
| unevaluatedProperties: false | |
| $defs: | |
| Mixins: | |
| $defs: | |
| Describable: | |
| properties: | |
| description: | |
| type: string | |
| Requireable: | |
| properties: | |
| required: | |
| type: boolean | |
| default: false | |
| Deprecatable: | |
| properties: | |
| deprecated: | |
| type: boolean | |
| default: false | |
| DescReqDep: | |
| allOf: | |
| - $ref: '#/$defs/Mixins/$defs/Describable' | |
| - $ref: '#/$defs/Mixins/$defs/Requireable' | |
| - $ref: '#/$defs/Mixins/$defs/Deprecatable' | |
| Extensible: | |
| patternProperties: | |
| '^x-': true | |
| WithSingleExample: | |
| properties: | |
| example: true | |
| examples: false | |
| WithExampleObjects: | |
| properties: | |
| example: false | |
| examples: | |
| type: object | |
| additionalProperties: | |
| $ref: '#Example' | |
| WithExamples: | |
| oneOf: | |
| - $ref: '#/$defs/Mixins/$defs/WithSingleExample' | |
| - $ref: '#/$defs/Mixins/$defs/WithExampleObjects' | |
| WithSchema: | |
| properties: | |
| schema: | |
| $ref: '#Schema' | |
| content: false | |
| WithSchemaAndExamples: | |
| allOf: | |
| - $ref: '#/$defs/Mixins/$defs/WithSchema' | |
| - $ref: '#/$defs/Mixins/$defs/WithExamples' | |
| WithContent: | |
| properties: | |
| schema: false | |
| content: | |
| type: object | |
| additionalProperties: | |
| $ref: '#MediaType' | |
| minProperties: 1 | |
| maxProperties: 1 | |
| WithNameAndLocation: | |
| required: | |
| - name | |
| - in | |
| properties: | |
| name: | |
| type: string | |
| in: | |
| type: string | |
| enum: | |
| - path | |
| - query | |
| - header | |
| - cookie | |
| WithExplodeAndReserved: | |
| properties: | |
| explode: | |
| type: boolean | |
| allowReserved: | |
| type: boolean | |
| default: false | |
| WithEmpty: | |
| properties: | |
| allowEmptyValue: | |
| type: boolean | |
| default: false | |
| WithExplodeReservedAndEmpty: | |
| allOf: | |
| - $refs: '#/$defs/Mixins/$defs/WithExplodeAndReserved' | |
| - $refs: '#/$defs/Mixins/$defs/WithEmpty' | |
| StyledSimple: | |
| allOf: | |
| - $refs: '#/$defs/Mixins/$defs/WithExplodeReservedAndEmpty' | |
| properties: | |
| style: | |
| type: string | |
| const: simple | |
| default: simple | |
| StyledMatrix: | |
| properties: | |
| style: | |
| type: string | |
| enum: | |
| - matrix | |
| - label | |
| - simple | |
| default: simple | |
| StyledFormOnly: | |
| allOf: | |
| - $refs: '#/$defs/Mixins/$defs/WithExplodeReservedAndEmpty' | |
| properties: | |
| style: | |
| type: string | |
| const: form | |
| default: form | |
| StyledFormComplexNoDefaultOrEmpty: | |
| allOf: | |
| - $refs: '#/$defs/Mixins/$defs/WithExplodeAndReserved' | |
| properties: | |
| style: | |
| type: string | |
| enum: | |
| - form | |
| - spaceDelimited | |
| - pipeDelimited | |
| - deepObject | |
| StyledFormComplex: | |
| allOf: | |
| - $refs: '#/$defs/Mixins/$defs/StyledFormComplexNoDefaultOrEmpty' | |
| - $refs: '#/$defs/Mixins/$defs/WithExplodeReservedAndEmpty' | |
| properties: | |
| style: | |
| default: form | |
| Objects: | |
| $defs: | |
| Reference: | |
| $id: '#Reference' | |
| type: object | |
| required: | |
| - $ref | |
| properties: | |
| $ref: | |
| type: string | |
| format: uri-reference | |
| Info: | |
| type: object | |
| required: | |
| - title | |
| - version | |
| allOf: | |
| - $ref: '#/$defs/Mixins/$defs/Describable' | |
| - $ref: '#/$defs/Mixins/$defs/Extensible' | |
| properties: | |
| title: | |
| type: string | |
| termsOfService: | |
| type: string | |
| format: uri-reference | |
| contact: | |
| $ref: '#Contact' | |
| license: | |
| $ref: '#License' | |
| $defs: | |
| Contact: | |
| $id: '#Contact' | |
| type: object | |
| allOf: | |
| - $ref: '#/$defs/Mixins/$defs/Extensible' | |
| properties: | |
| name: | |
| type: string | |
| url: | |
| type: string | |
| format: uri-reference | |
| email: | |
| type: string | |
| format: email | |
| unevaluatedProperties: false | |
| License: | |
| $id: '#License' | |
| type: object | |
| required: | |
| - name | |
| allOf: | |
| - $ref: '#/$defs/Mixins/$defs/Extensible' | |
| properties: | |
| name: | |
| type: string | |
| url: | |
| type: string | |
| format: uri-reference | |
| unevaluatedProperties: false | |
| Server: | |
| $id: '#Server' | |
| type: object | |
| required: | |
| - url | |
| allOf: | |
| - $ref: '#/$defs/Mixins/$defs/Describable' | |
| - $ref: '#/$defs/Mixins/$defs/Extensible' | |
| properties: | |
| url: | |
| type: string | |
| variables: | |
| type: object | |
| additionalProperties: | |
| type: object | |
| required: | |
| - default | |
| allOf: | |
| - $ref: '#/$defs/Mixins/$defs/Describable' | |
| - $ref: '#/$defs/Mixins/$defs/Extensible' | |
| properties: | |
| enum: | |
| type: array | |
| items: | |
| type: string | |
| default: | |
| type: string | |
| unevaluatedProperties: false | |
| unevaluatedProperties: false | |
| Response: | |
| $id: '#Response' | |
| oneOf: | |
| - $ref: '#Reference' | |
| - type: object | |
| required: | |
| - description | |
| allOf: | |
| - $ref: '#/$defs/Mixins/$defs/Describable' | |
| - $ref: '#/$defs/Mixins/$defs/Extensible' | |
| properties: | |
| headers: | |
| type: object | |
| additionalProperties: | |
| $ref: '#Header' | |
| content: | |
| type: object | |
| additionalProperties: | |
| $ref: '#MediaType' | |
| links: | |
| type: object | |
| additionalProperteis: | |
| $ref: '#Link' | |
| unevaluatedProperties: false | |
| MediaType: | |
| $id: '#MediaType' | |
| type: object | |
| allOf: | |
| - $ref: '#/$defs/Mixins/$defs/WithSchemaAndExamples' | |
| properties: | |
| encoding: | |
| type: object | |
| allOf: | |
| - $ref: '#/$defs/Mixins/$defs/StyledFormComplexNoDefaultOrEmpty' | |
| properties: | |
| contentType: | |
| type: string | |
| headers: | |
| type: object | |
| additionalProperties: | |
| $ref: '#Header' | |
| unevaluatedProperties: false | |
| Example: | |
| $id: '#Example' | |
| oneOf: | |
| - $ref: '#Reference' | |
| - type: object | |
| allOf: | |
| - $ref: '#/$defs/Mixins/$defs/Describable' | |
| - $ref: '#/$defs/Mixins/$defs/Extensible' | |
| properties: | |
| summary: | |
| type: string | |
| value: true | |
| externalValue: | |
| type: string | |
| format: uri-reference | |
| unevaluatedProperties: false | |
| Header: | |
| $id: '#Header' | |
| oneOf: | |
| - $ref: '#Reference' | |
| - type: object | |
| required: | |
| - schema | |
| allOf: | |
| - $ref: '#/$defs/Mixins/$defs/DescReqDep' | |
| - $ref: '#/$defs/Mixins/$defs/Extensible' | |
| oneOf: | |
| - allOf: | |
| - $ref: '#/$defs/Mixins/$defs/WithSchemaAndExamples' | |
| - $ref: '#/$defs/Mixins/$defs/StyledSimple' | |
| - allOf: | |
| - $ref: '#/$defs/Mixins/$defs/WithContent' | |
| - $ref: '#/$defs/Mixins/$defs/WithEmpty' | |
| unevaluatedProperties: false | |
| Paths: | |
| $id: '#Paths' | |
| type: object | |
| allOf: | |
| - $ref: '#/$defs/Mixins/$defs/Extensible' | |
| patternProperties: | |
| '^\/': | |
| type: object | |
| patternProperties: | |
| '^(get|put|post|delete|options|head|patch|trace)$': | |
| $ref: '#Operation' | |
| properties: | |
| servers: | |
| type: array | |
| items: | |
| $ref: 'Server' | |
| parameters: | |
| type: array | |
| items: | |
| $ | |
| unevaluatedProperties: false | |
| Operation: | |
| $id: '#Operation' | |
| type: object | |
| required: | |
| - responses | |
| allOf: | |
| - $ref: '#/$defs/Mixins/$defs/Describable' | |
| - $ref: '#/$defs/Mixins/$defs/Deprecatable' | |
| - $ref: '#/$defs/Mixins/$defs/Extensible' | |
| properties: | |
| tags: | |
| type: array | |
| items: | |
| type: string | |
| summary: | |
| type: string | |
| externalDocs: | |
| $ref: '#ExternalDocumentation' | |
| operationId: | |
| type: string | |
| parameters: | |
| type: array | |
| items: | |
| $ref: '#Parameter' | |
| requestBody: | |
| $ref: '#RequestBody' | |
| responses: | |
| $ref: '#Responses' | |
| callback: | |
| $ref: '#Callback' | |
| security: | |
| type: array | |
| items: | |
| $ref: '#SecurityRequirement' | |
| servers: | |
| type: array | |
| items: | |
| $ref: '#Server' | |
| unevaluatedProperties: false | |
| Responses: | |
| $id: '#Responses' | |
| type: object | |
| allOf: | |
| - $ref: '#/$defs/Mixins/$defs/Extensible' | |
| properties: | |
| default: | |
| $ref: '#Response' | |
| patternProperties: | |
| '[1-5](?:\d{2}|XX)': | |
| $ref: '#Response' | |
| minProperties: 1 | |
| unevaluatedProperties: false | |
| SecurityRequirement: | |
| $id: '#SecurityRequirement' | |
| type: object | |
| additionalProperties: | |
| type: array | |
| items: | |
| type: string | |
| Tag: | |
| $id: '#Tag' | |
| type: object | |
| required: | |
| - name | |
| allOf: | |
| - $ref: '#/$defs/Mixins/$defs/Describable' | |
| - $ref: '#/$defs/Mixins/$defs/Extensible' | |
| properties: | |
| name: | |
| type: string | |
| externalDocs: | |
| $ref: '#ExternalDocumentation' | |
| unevaluatedProperties: false | |
| Parameter: | |
| $id: '#Parameter' | |
| oneOf: | |
| - $ref: '#Reference' | |
| - type: object | |
| allOf: | |
| - $ref: '#/$defs/Mixins/$defs/WithNameAndLocation' | |
| - $ref: '#/$defs/Mixins/$defs/Extensible' | |
| - oneOf: | |
| - allOf: | |
| - $ref: '#PathParam' | |
| - $ref: '#/$defs/Mixins/$defs/Describable' | |
| - $ref: '#/$defs/Mixins/$defs/Deprecatable' | |
| - required: | |
| - required | |
| properties: | |
| required: | |
| const: true | |
| default: true | |
| - allOf: | |
| - anyOf: | |
| - $ref: '#QueryParam' | |
| - $ref: '#HeaderParam' | |
| - $ref: '#CookieParam' | |
| - $ref: '#/$defs/Mixins/$defs/DescReqDep' | |
| oneOf: | |
| - allOf: | |
| - required: | |
| - schema | |
| - $ref: '#/$defs/Mixins/$defs/WithSchemaAndExamples' | |
| - oneOf: | |
| - allOf: | |
| - $ref: '#PathParam' | |
| - $ref: '#/$defs/Mixins/$defs/StyledMatrix' | |
| - allOf: | |
| - $refs: '#QueryParam' | |
| - $refs: '#/$defs/Mixins/$defs/StyledFormComplex' | |
| - allOf: | |
| - $ref: '#HeaderParam' | |
| - $ref: '#/$defs/Mixins/$defs/StyledSimple' | |
| - allOf: | |
| - $ref: '#CookieParam' | |
| - $refs: '#/$defs/Mixins/$defs/StyledFormOnly' | |
| - allOf: | |
| - required: | |
| - content | |
| - $ref: '#/$defs/Mixins/$defs/WithContent' | |
| - $ref: '#/$defs/Mixins/$defs/WithEmpty' | |
| unevaluatedProperties: false | |
| $defs: | |
| PathParam: | |
| $id: '#PathParam' | |
| properties: | |
| in: | |
| const: path | |
| QueryParam: | |
| $id: '#QueryParam' | |
| properties: | |
| in: | |
| const: query | |
| HeaderParam: | |
| $id: '#HeaderParam' | |
| properties: | |
| in: | |
| const: header | |
| CookieParam: | |
| $id: '#CookieParam' | |
| properties: | |
| in: | |
| const: cookie | |
| RequestBody: | |
| $id: '#RequestBody' | |
| required: | |
| - content | |
| allOf: | |
| - $ref: '#/$defs/Mixins/$defs/Describable' | |
| - $ref: '#/$defs/Mixins/$defs/Requireable' | |
| - $ref: '#/$defs/Mixins/$defs/Extensible' | |
| properties: | |
| content: | |
| type: object | |
| additionalProperties: | |
| $ref: '#MediaType' | |
| unevaluatedProperties: false | |
| SecurityScheme: | |
| $id: '#SecurityScheme' | |
| oneOf: | |
| - $ref: '#Reference' | |
| - type: object | |
| required: | |
| -type | |
| allOf: | |
| - $ref: '#/$defs/Mixins/$defs/Describable' | |
| - $ref: '#/$defs/Mixins/$defs/Extensible' | |
| properties: | |
| type: | |
| string: | |
| enum: | |
| - apiKey | |
| - http | |
| - bearer | |
| - oauth2 | |
| - openIdConnect | |
| oneOf: | |
| - $ref: '#APIKey' | |
| - $ref: '#HTTP' | |
| - $ref: '#OAuth2' | |
| - $ref: '#OpenIdConnect' | |
| unevaluatedProperties: false | |
| $defs: | |
| APIKey: | |
| $id: '#APIKey' | |
| properties: | |
| type: | |
| const: apiKey | |
| allOf: | |
| - $ref: '#/$defs/Mixins/$defs/WithNameAndLocation' | |
| not: | |
| $ref: '#PathParam' | |
| HTTP: | |
| $id: '#HTTP' | |
| required: | |
| - scheme | |
| properties: | |
| scheme: | |
| type: string | |
| oneOf: | |
| - properties: | |
| type: | |
| const: http | |
| - properties: | |
| type: | |
| const: bearer | |
| bearerFormat: | |
| type: string | |
| OAuth2: | |
| $id: '#OAuth2' | |
| required: | |
| - flows | |
| properties: | |
| type: | |
| const: oauth2 | |
| flows: | |
| $ref: '#OAuthFlows' | |
| OpenIdConnect: | |
| $id: '#OpenIdConnect' | |
| required: | |
| - openIdConnectUrl | |
| properties: | |
| type: | |
| const: openIdConnect | |
| openIdConnectUrl: | |
| type: string | |
| format: uri | |
| OAuthFlows: | |
| $id: '#OAuthFlows' | |
| type: object | |
| allOf: | |
| - $ref: '#/$defs/Mixins/$defs/Extensible' | |
| properties: | |
| implicit: | |
| allOf: | |
| - required: | |
| - scopes | |
| - $ref: '#CommonFlow' | |
| - $ref: '#AuthorizationFlow' | |
| - $ref: '#/$defs/Mixins/$defs/Extensible' | |
| unevaluatedProperties: false | |
| password: | |
| allOf: | |
| - $ref: '#CommonFlow' | |
| - $ref: '#TokenFlow' | |
| - $ref: '#/$defs/Mixins/$defs/Extensible' | |
| unevaluatedProperties: false | |
| clientCredentials: | |
| allOf: | |
| - $ref: '#CommonFlow' | |
| - $ref: '#TokenFlow' | |
| - $ref: '#/$defs/Mixins/$defs/Extensible' | |
| unevaluatedProperties: false | |
| authorizationCode: | |
| allOf: | |
| - $ref: '#CommonFlow' | |
| - $ref: '#TokenFlow' | |
| - $ref: '#AuthorizationFlow' | |
| - $ref: '#/$defs/Mixins/$defs/Extensible' | |
| unevaluatedProperties: false | |
| unevaluatedProperties: false | |
| $defs: | |
| Common: | |
| $id: '#CommonFlow' | |
| properties: | |
| refreshUrl: | |
| type: string | |
| format: uri-reference | |
| scopes: | |
| type: object | |
| additionalProperties: | |
| type: string | |
| Token: | |
| $id: '#TokenFlow' | |
| required: | |
| - tokenUrl | |
| properties: | |
| tokenUrl: | |
| type: string | |
| format: uri-reference | |
| Authorization: | |
| $id: '#AuthorizationFlow' | |
| required: | |
| - authorizationUrl | |
| properties: | |
| authorizationUrl: | |
| type: string | |
| format: uri-reference | |
| Link: | |
| $id: '#Link' | |
| oneOf: | |
| - $ref: '#Reference' | |
| - type: object | |
| allOf: | |
| - $ref: '#/$defs/Mixins/$defs/Describable' | |
| - $ref: '#/$defs/Mixins/$defs/Extensible' | |
| oneOf: | |
| - properties: | |
| operationRef: | |
| type: string | |
| format: uri-reference | |
| operationId: false | |
| - properties: | |
| operationRef: false | |
| operationId: | |
| type: string | |
| properties: | |
| parameters: | |
| type: object | |
| additionalProperties: true | |
| requestBody: true | |
| server: | |
| $ref: '#Server' | |
| unevaluatedProperties: false | |
| Callback: | |
| $id: '#Callback' | |
| oneOf: | |
| - $ref: '#Reference' | |
| - type: object | |
| allOf: | |
| - $ref: '#/$defs/Mixins/$defs/Extensible' | |
| unevaluatedProperties: false | |
| Schema: | |
| $id: '#Schema' | |
| oneOf: | |
| - $ref: '#Reference' | |
| - type: object | |
| allOf: | |
| - $ref: 'http://json-schema.org/draft-04/schema#' | |
| - $ref: '#SchemaRestrictions' | |
| - $ref: '#SchemaExtensions' | |
| - $ref: '#/$defs/Mixins/$def/Extensible' | |
| unevaluatedProperties: false | |
| $defs: | |
| Restrictions: | |
| $id: '#SchemaRestrictions' | |
| properties: | |
| type: | |
| not: | |
| const: 'null' | |
| not: | |
| $ref: '#/$defs/Schema' | |
| allOf: | |
| type: array | |
| items: | |
| $ref: '#/$defs/Schema' | |
| oneOf: | |
| type: array | |
| items: | |
| $ref: '#/$defs/Schema' | |
| anyOf: | |
| type: array | |
| items: | |
| $ref: '#/$defs/Schema' | |
| items: | |
| $ref: '#/$defs/Schema' | |
| properties: | |
| type: object | |
| additionalProperties: | |
| $ref: '#/$defs/Schema' | |
| additionalProperties: | |
| oneOf: | |
| - $ref: '#/$defs/Schema' | |
| - type: boolean | |
| default: true | |
| patternProperties: false | |
| Extensions: | |
| $id: '#SchemaExtensions' | |
| properties: | |
| nullable: | |
| type: boolean | |
| default: false | |
| discriminator: | |
| $ref: '#Discriminator' | |
| readOnly: | |
| type: boolean | |
| default: false | |
| writeOnly: | |
| type: boolean | |
| default: false | |
| example: true | |
| externalDocs: | |
| $ref: '#ExternalDocumentation' | |
| deprecated: | |
| type: boolean | |
| default: false | |
| xml: | |
| $ref: '#XML' | |
| Discriminator: | |
| $id: '#Discriminator' | |
| type: object | |
| required: | |
| - propertyName | |
| properties: | |
| propertyName: | |
| type: string | |
| mapping: | |
| type: object | |
| additionalProperties: | |
| type: string | |
| XML: | |
| $id: '#XML' | |
| type: object | |
| properties: | |
| name: | |
| type: string | |
| namespace: | |
| type: string | |
| format: url | |
| prefix: | |
| type: string | |
| attribute: | |
| type: boolean | |
| default: false | |
| wrapped: | |
| type: boolean | |
| default: false | |
| patternProperties: | |
| '^x-': true | |
| additionalProperties: false | |
| Components: | |
| $id: '#Components' | |
| type: object | |
| allOf: | |
| - $ref: '#/$defs/Mixins/$defs/Extensible' | |
| - additionalProperties: | |
| $comment: All sub-objects have the same property name constraints | |
| type: object | |
| propertyNames: | |
| pattern: '^[a-zA-Z0-9\.\-_]+$' | |
| properties: | |
| schemas: | |
| additionalProperties: | |
| $ref: '#Schema' | |
| responses: | |
| additionalProperties: | |
| $ref: '#Responses' | |
| parameters: | |
| additionalProperties: | |
| $ref: '#Parameter' | |
| examples: | |
| additionalProperties: | |
| $ref: '#Example' | |
| requestBodies: | |
| additionalProperties: | |
| $ref: '#RequestBody' | |
| headers: | |
| additionalProperties: | |
| $ref: '#Header' | |
| links: | |
| additionalProperties: | |
| $ref: '#Link' | |
| callbacks: | |
| additionalProperties: | |
| $ref: '#Callback' | |
| unevaluatedProperties: true |
Author
What is the likelihood of unevaluatedProperties being accepted as the json-schema for OAS 3.0? OAI/OpenAPI-Specification#1032 was accepted last month and does not include unevaluatedProperties.
Author
@dskvr unevaluatedProperties is part of the next draft of JSON Schema, so #1032 couldn't make use of it yet.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This is a refactor of OAI/OpenAPI-Specification#1270 which uses draft-06 and draft-07 features, as well as several draft-08 proposals. It illustrates different things for the JSON Schema and OpenAPI projects.
unevaluatedProperties, in a complex real-world scenario.unevaluatedPropertiesallows us to eliminate the extensive duplication in PR 1270.High level overview
I broke the schema up into two kinds of definitions: mixins and objects. The mixins collect various individual or groups of properties that are re-used in many places. This includes some
oneOfcombinations which are either mutually exclusive due to a pinnedenumvalue, or I made them mutually exclusive by forbidding each other's properties by setting the property schemas tofalse(see Example and Examples for... er... examples :-)While organizing the mixins like this maximizes re-use, it does obscure the structure of things a bit. However, I don't think that schemas should be primary documentation- that's what the spec is for. The schema needs to be correct and maintainable more than it needs to be obvious for less techncial human readers.
Here is a quick guide to the post-draft-04 features used above:
draft-06
constin place of single-elementenumtruein place of{}falsein place of{"not": {}}$idinstead ofid$idplain name fragments$refstyles, the choice is not otherwise significant herepropertyNames, a schema applied to all property names in the instancepatternProperties"format": "uri-reference"instead ofurirefdraft-07
if/then/else, although some of theoneOfs could be reworked to use itcontainsor any of the newer formatsdraft-08 proposals
definitionsto$defs$ref,$id, and$schemaas it has no validation effectunevaluatedPropertiesgets its own section belowunevaluatedPropertiesThe
unevaluatedPropertiesproposal is key, so let's go through an example of how it works.TL;DR: It does what you probably want
additionalPropertiesto do when you put it next toanyOf,allOf, oroneOf.Both of the following schemas successfully validate
{"foo": 1, "common": true}and{"bar": "hi", "common": false}, but fail on{"foo": 1, "common": true, "oof" 2}for different reasons in each schema. Let's take a look at what those different reasons are:In the above schema,
{"foo": 1, "common": true, "oof: 2}fails because of theadditionalProperties: falseadjacent to the definition of "foo". It prevents "off", and any other property but "foo" or "common", from validating.However, note that
common: {type: boolean}is duplicated in the two branches of theanyOf. This is becauseadditionalPropertiesonly "sees"propertiesandpatternPropertiesthat are defined immediately adjacent to it in the same schema object. This is also whyadditionalProperties: falseis duplicated. IfadditionalPropertieswere outside of theanyOf, it would not have any immediately adjacentpropertiesorpatternPropertiesso any object with any properties would fail validation.One benefit of the way
additionalPropertiesis defined is that you can compute the set of property names to which it applies statically from the schema alone, without evaluating an instance.Now let's look at it with
unevaluatedProperties:Here we see
commondefined once at the top level, alongside a top levelunevaluatedProperties: falsewhich replaces the two separate uses ofadditionalProperties: false.unevaluatedPropertiescan "see" into theanyOf, because it applies to any property that has not successfully validated against any subschema of any keyword adjacent to it.In this example, the
anyOfand the outerpropertiesare both adjacent tounevaluatedProperties. When validating{"foo": 1, "common": true}, "common" is successfully evaluated against a subschema of the adjacentproperties, and "foo" is successfully evaluated against a subschema under theanyOf.However, when validating
{"foo": 1, "common": true, "oof": 2}"oof" has not been validated against any defined subschema, so it is considered to be unevaluated. And since we have set
unevaluatedPropertiestofalse, its presence causes validation to fail.Considering a more complex
anyOf:With this schema,
{"bar": "hi", "common": false, "oof": 2}is valid, while{"foo": 1, "common": true, "oof": 2}is not. This shows howunevaluatedPropertiesis dynamic in nature.When the first instance matches the subschema with "bar", it causes "bar" and "oof" to be evaluated. And "common" is still evaluated by the top-level
properties. Therefore there are no unevaluated properties in the instance and validation passes.The second instance fails the "bar" branch of the
anyOf. This means that "oof" is not considered to have been evaluated. Even though it passes the "oof" subschema in the "bar" branch, since the whole "bar" branch fails validation (because there is no "bar" in the instance), no subschema in the branch contributes to the evaluation count.The second instance only passes the "foo" branch, so only "foo" and "common" are considered to have been evaluated. "oof" has not been, so
unevaluatedProperties: falsecauses it to fail.