diff --git a/content/2019-09/validation/type.markdown b/content/2019-09/validation/type.markdown index 281ca650..eae00b73 100644 --- a/content/2019-09/validation/type.markdown +++ b/content/2019-09/validation/type.markdown @@ -37,12 +37,11 @@ JSON parsers. | `"string"` | A JSON string | [UTF-8](https://en.wikipedia.org/wiki/UTF-8) Unicode encoding | Note that while the JSON grammar does not distinguish between integer and real -numbers, JSON Schema provides the [`integer`]({{< ref -"2019-09/validation/type" >}}) logical type that matches either integers (such -as `2`), or real numbers where the fractional part is zero (such as `2.0`). -Additionally, numeric constructs inherent to floating point encodings (like -`NaN` and `Infinity`) are not permitted in JSON. However, the negative zero -(`-0`) is permitted. +numbers, JSON Schema provides the `integer` logical type that matches either +integers (such as `2`), or real numbers where the fractional part is zero (such +as `2.0`). Additionally, numeric constructs inherent to floating point +encodings (like `NaN` and `Infinity`) are not permitted in JSON. However, the +negative zero (`-0`) is permitted. {{}} To avoid interoperability issues, do not produce JSON documents with numbers that exceed the [IETF RFC diff --git a/content/draft4/core/id.markdown b/content/draft4/core/id.markdown index d6236ae3..ba337ba8 100644 --- a/content/draft4/core/id.markdown +++ b/content/draft4/core/id.markdown @@ -18,3 +18,165 @@ related: - vocabulary: core keyword: $schema --- + +The [`id`]({{< ref "draft4/core/id" >}}) keyword explicitly turns a schema +into a _schema resource_ (a schema that is associated with a URI). Relative +URIs are resolved against the _current_ base URI, which is either the closest +parent [`id`]({{< ref "draft4/core/id" >}}) keyword (applicable in the case +of compound schemas), or the base URI as determined by the context on which the +schema is declared (i.e. serving a schema over HTTP _may_ implicitly award it +such URL as the base). + +{{}} + +This keyword directly applies (without modifications or extensions) the concept +of URIs to schemas. **If you are having a hard time following the concepts +discussed in this page, it is probably because you don't have a strong grasp of +URIs yet** (a notably hard but universal pre-requisite!). + +To learn more about URIs, we strongly suggest studying the [IETF RFC +3986](https://www.rfc-editor.org/info/rfc3986) URI standard. To avoid +confusion, note that there is also a [WHATWG URL +Standard](https://url.spec.whatwg.org) that targets URLs in the context of web +browsers. However, JSON Schema only implements and expects the IETF original +standard. + +{{}} + +{{}} + +In JSON Schema, schema identifiers are merely identifiers and no behaviour is +imposed on them. In particular, JSON Schema does not guarantee that a schema +with an HTTP URL identifier is actually resolvable at such URL. To avoid +surprises, JSON Schema implementations must be careful with automatically +sending remote network requests when encountering supposely resolvable schema +identifiers. + +{{}} + +{{}} + +It is strongly recommended for every schema file to explicitly declare an +_absolute_ URI using this keyword. By doing so, you completely avoid various +complex URI resolution edge cases, mainly when the base URI is implicit and +context-dependent. + +If you are serving schemas over the network (i.e. over HTTP), it is common to +set this keyword to the target URL. However, if your schemas are not accessible +over the network, prefer using a +[URN](https://en.wikipedia.org/wiki/Uniform_Resource_Name) (with a valid +namespace registered by +[IANA](https://www.iana.org/assignments/urn-namespaces/urn-namespaces.xhtml)) +or a non-locatable URI scheme such as a [Tag URI](https://www.taguri.org). + +{{}} + +To debug the role of the [`id`]({{< ref "draft4/core/id" >}}) keyword on +a schema (particularly schemas with embedded resources), try the [`jsonschema +inspect`](https://github.com/sourcemeta/jsonschema/blob/main/docs/inspect.markdown) +command. This command prints detailed information about each schema resource, +subschema, location, and reference present in the schema. For example: + +```sh +$ jsonschema inspect schema.json +(RESOURCE) URI: https://example.com/schema + Type : Static + Root : https://example.com/schema + Pointer : + Base : https://example.com/schema + Relative Pointer : + Dialect : http://json-schema.org/draft-04/schema# + Base Dialect : http://json-schema.org/draft-04/schema# + Parent : + Instance Location : + +... + +(SUBSCHEMA) URI: https://example.com/schema#/properties/foo + Type : Static + Root : https://example.com/schema + Pointer : /properties/foo + Base : https://example.com/schema + Relative Pointer : /properties/foo + Dialect : http://json-schema.org/draft-04/schema# + Base Dialect : http://json-schema.org/draft-04/schema# + Parent : + Instance Location : /foo + +... + +(REFERENCE) ORIGIN: /$schema + Type : Static + Destination : http://json-schema.org/draft-04/schema + - (w/o fragment) : http://json-schema.org/draft-04/schema + - (fragment) : +``` + +## Examples + +{{}} +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "id": "https://example.com/schemas/even-number.json", + "type": "number", + "multipleOf": 2 +} +{{}} + +{{}} +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "id": "tag:example.com,2025:even-number", + "type": "number", + "multipleOf": 2 +} +{{}} + +{{}} +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "id": "urn:example:even-number", + "type": "number", + "multipleOf": 2 +} +{{}} + +{{}} +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "id": "https://example.com/schemas/user.json", + "type": "object", + "properties": { + "name": { "$ref": "#nonEmptyString" }, + "email": { "$ref": "#nonEmptyString" } + }, + "definitions": { + "nonEmptyString": { + "id": "#nonEmptyString", + "type": "string", + "minLength": 1 + } + } +} +{{}} + +{{}} +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "id": "https://example.com/schemas/root.json", + "properties": { + "foo": { + "id": "foo.json" + }, + "bar": { + "id": "/schemas/bar.json" + }, + "baz": { + "id": "https://absolute.example/baz.json", + "items": { + "id": "deep" + } + } + } +} +{{}} diff --git a/content/draft4/core/ref.markdown b/content/draft4/core/ref.markdown index dd593811..7e238c62 100644 --- a/content/draft4/core/ref.markdown +++ b/content/draft4/core/ref.markdown @@ -20,3 +20,210 @@ related: - vocabulary: validation keyword: definitions --- + +The [`$ref`]({{< ref "draft4/core/ref" >}}) keyword enables a schema to +reference another schema by its URI, effectively importing its keywords into the +current evaluation process. This keyword is the cornerstone of schema +composition, allowing complex schemas to be created out of simpler ones. A +reference may set its URI fragment to a [JSON +Pointer](https://www.rfc-editor.org/rfc/rfc6901) that determines the destination +of the reference after first resolving the rest of the URI. + +{{}} + +In JSON Schema [Draft 7](/draft7) and earlier versions, **any subschema +declaring the [`$ref`]({{< ref "draft4/core/ref" >}}) keyword is considered to +be a _reference object_ and any other sibling keyword is silently ignored**. As +a consequence, subschemas with references that make use of other keywords must +artificially wrap the reference into its own subschema using keywords like +[`allOf`]({{< ref "draft4/validation/allof" >}}). + +{{}} + +{{}} + +**Avoid referencing other schema files using their file paths**. While some +implementations support this by automatically constructing schema URIs that +make use of the `file://` scheme, this is not enforced behaviour. The only +standard and guaranteed mechanism of declaring a schema URI for identification +and referencing purposes is through the [`id`]({{< ref "draft4/core/id" >}}) keyword. + +{{}} + +{{}} + +The target of a reference must be a schema. Referencing a JSON value that is +not unambiguously recognised as a schema leads to undefined behaviour. This +not only includes referencing arbitrary JSON files (the obvious case), but +also referencing parts of a schema that a JSON Schema evaluator does not +consider to be a subschema. + +{{}} + +References are either _internal_ (pointing at schemas within the same schema +definition) or _external_ (pointing at schema resources outside the given schema +definition). If the reference is a relative URI, it is resolved against the +_current_ base URI, which is either the closest parent URI as set by the +[`id`]({{< ref "draft4/core/id" >}}) keyword, or the base URI as determined by +the context on which the schema is declared. Schema wrappers like OpenAPI are +notable examples of the latter. A relative reference from a schema embedded in +an OpenAPI specification is resolved from the root of the API specification, and +not from the root of the schema. + +{{}} + +It is highly recommended to make use of _external_ references to break down +complex monolithic schemas into smaller schema files. However, for performance +and integrity reasons, avoid resolving these external schemas (i.e. over HTTP +or the filesystem) at runtime. + +You can automatically inline external references at build time using the +[`jsonschema +bundle`](https://github.com/sourcemeta/jsonschema/blob/main/docs/bundle.markdown) +command. + +{{}} + +Note that a reference to an absolute URI does not necessarily mean that the +reference is external. Conversely, a reference to a relative URI does not +necessarily mean that the reference is internal. When encountering any type +of reference, a JSON Schema implementation will check if the root schema +resource or its nested schema resources (if any) declare the canonically +resolved version of such URI through the [`id`]({{< ref "draft4/core/id" +>}}) keyword. If so, the reference is considered internal. This +internal-first lookup is what enables the standard +[bundling](https://json-schema.org/blog/posts/bundling-json-schema-compound-documents) +process. + +{{}} + +If you are having a hard time understanding references and some of its more +subtle scenarios (like base URI resolution), it is probably because you don't +have a strong grasp of URIs yet (a notably hard but universal +pre-requisite!). + +To learn more about URIs, we strongly suggest studying the [IETF RFC +3986](https://www.rfc-editor.org/info/rfc3986) URI standard. To avoid +confusion, note that there is also a [WHATWG URL +Standard](https://url.spec.whatwg.org) that targets URLs in the context of +web browsers. However, JSON Schema only implements and expects the IETF +original standard. As a notable extension, this keyword supports referencing +specific parts of a schema through the use of a JSON Pointer, so we also +recommend studying the [IETF RFC 6901](https://www.rfc-editor.org/info/rfc6901) +JSON Pointer standard and its [URI fragment identifier +representation](https://www.rfc-editor.org/rfc/rfc6901#section-6). + +{{}} + +To debug references and how JSON Schema is interpreting your relative URIs, +try the [`jsonschema +inspect`](https://github.com/sourcemeta/jsonschema/blob/main/docs/inspect.markdown) +command. This command prints detailed information about each schema reference +and of each location of the schema. For example: + +```sh +$ jsonschema inspect schema.json +... + +(REFERENCE) ORIGIN: /properties/foo/$ref + Type : Static + Destination : https://example.com/schemas/example#/definitions/uuid + - (w/o fragment) : https://example.com/schemas/example + - (fragment) : /definitions/uuid + +... +``` + +## Examples + +{{}} +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "properties": { + "foo": { + "type": "string", + "$ref": "#/definitions/test" + } + }, + "definitions": { + "test": { "minLength": 2 } + } +} +{{}} + +{{}} +12345 +{{}} + +{{}} +"foo" +{{}} + +{{}} +"x" +{{}} + +{{}} +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "id": "https://example.com/my-schema", + "properties": { + "byRelativeFragmentPointer": { + "$ref": "#/definitions/helper" + }, + "byAbsoluteFragmentPointer": { + "$ref": "https://example.com/my-schema#/definitions/helper" + }, + "byRelativeURI": { + "$ref": "my-helper" + }, + "byRelativeRootPathURI": { + "$ref": "/my-helper" + }, + "byRelativeBackslashURI": { + "$ref": "my-schema/../my-helper" + }, + "byAbsoluteURI": { + "$ref": "https://example.com/my-helper" + } + }, + "definitions": { + "helper": { + "id": "my-helper", + "type": "string" + } + } +} +{{}} + +{{}} +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "id": "https://example.com/my-schema", + "properties": { + "byAbsoluteURI": { + "$ref": "https://example.com/my-other-schema" + }, + "byRelativeURI": { + "$ref": "my-other-schema" + }, + "byRelativeRootPathURI": { + "$ref": "/my-other-schema" + }, + "byRelativeBackslashURI": { + "$ref": "my-schema/../my-other-schema" + } + } +} +{{}} + +{{}} +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "properties": { + "byAbsoluteURI": { + "$ref": "urn:example:my-other-schema" + } + } +} +{{}} diff --git a/content/draft4/core/schema.markdown b/content/draft4/core/schema.markdown index d2218fdb..0755d0fe 100644 --- a/content/draft4/core/schema.markdown +++ b/content/draft4/core/schema.markdown @@ -17,3 +17,134 @@ related: - vocabulary: validation keyword: definitions --- + +The [`$schema`]({{< ref "draft4/core/schema" >}}) keyword serves to explicitly +associate a _schema resource_ with the JSON Schema dialect that defines it, +where the dialect is the identifier of a meta-schema that defines the keywords +in use and imposes syntactic constraints on its schema instances. If the +[`$schema`]({{< ref "draft4/core/schema" >}}) keyword is not declared, the +schema inherits its context-specific or implementation-specific default +dialect. + +{{}} It is common to avoid the [`$schema`]({{< ref "draft4/core/schema" >}}) keyword when working with +[OpenAPI](https://www.openapis.org). This is possible because the OpenAPI +specification clearly documents what the default JSON Schema dialect is for +every version. For example, [OpenAPI +v3.1.1](https://spec.openapis.org/oas/latest.html#json-schema-keywords) defines +the default dialect as `https://spec.openapis.org/oas/3.1/dialect/base`. +{{}} + +Strictly-compliant JSON Schema implementations will refuse to process a schema +whose dialect cannot be unambiguously determined. + +{{}} To avoid undefined behavior, it is generally recommended to +always explicitly set the dialect of a schema using the [`$schema`]({{< ref "draft4/core/schema" >}}) keyword. This ensures that less strict +implementations unambiguously know how to process the schema and don't attempt +to guess.{{}} + +Note that the [`$schema`]({{< ref "draft4/core/schema" >}}) keyword can occur +multiple times in the same schema, and not only at the top-level. This is often +the case when performing [JSON Schema +Bundling](https://github.com/sourcemeta/jsonschema/blob/main/docs/bundle.markdown) +to inline externally referenced schemas that might be based on different +dialects of JSON Schema. + +{{}}JSON Schema prohibits referencing meta-schemas using +relative URIs. The fundamental reason for this is that resolving the +meta-schema is necessary for correctly determining the base URI of the schema, +from which a relative meta-schema reference would be resolved, introducing a +circular problem. + +A common occurrence of this issue is setting the [`$schema`]({{< ref "draft4/core/schema" >}}) keyword to a relative path, which is again invalid +according to the specification.{{}} + +{{}}JSON Schema prohibits the use of the this keyword on +arbitrary subschemas that do not represent schema resources. It can only be +present at the root of the schema (an implicit schema resource) or as a sibling +of the [`id`]({{< ref "draft4/core/id" >}}) keyword (an explicit schema +resource).{{}} + +A schema is considered syntactic valid if it successfully validates against its +dialect meta-schema. You can validate a schema against its meta-schema using +the [`jsonschema +metaschema`](https://github.com/sourcemeta/jsonschema/blob/main/docs/metaschema.markdown) +command. For example: + +```sh +$ jsonschema metaschema my-schema.json +``` + +To debug the role of the [`$schema`]({{< ref "draft4/core/schema" >}}) +keyword on a schema (particularly schemas with embedded resources), try the +[`jsonschema +inspect`](https://github.com/sourcemeta/jsonschema/blob/main/docs/inspect.markdown) +command. This command prints detailed information about each schema resource, +subschema, location, and reference present in the schema. For example: + +```sh +$ jsonschema inspect schema.json +(RESOURCE) URI: https://example.com/schema + Type : Static + Root : https://example.com/schema + Pointer : + Base : https://example.com/schema + Relative Pointer : + Dialect : http://json-schema.org/draft-04/schema# + Base Dialect : http://json-schema.org/draft-04/schema# + Parent : + Instance Location : + +... + +(SUBSCHEMA) URI: https://example.com/schema#/properties/foo + Type : Static + Root : https://example.com/schema + Pointer : /properties/foo + Base : https://example.com/schema + Relative Pointer : /properties/foo + Dialect : http://json-schema.org/draft-04/schema# + Base Dialect : http://json-schema.org/draft-04/schema# + Parent : + Instance Location : /foo + +... + +(REFERENCE) ORIGIN: /$schema + Type : Static + Destination : http://json-schema.org/draft-04/schema + - (w/o fragment) : http://json-schema.org/draft-04/schema + - (fragment) : +``` + +## Examples + +{{}} +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "type": "string" +} +{{}} + +{{}} +{ + "items": [ { "type": "number" } ] +} +{{}} + +{{}} +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "properties": { + "price": { "type": "number" }, + "discount": { + "$ref": "#/definitions/discount" + } + }, + "definitions": { + "discount": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "number" + } + } +} +{{}} diff --git a/content/draft4/validation/additionalItems.markdown b/content/draft4/validation/additionalItems.markdown index 2a1ab8a5..6e008297 100644 --- a/content/draft4/validation/additionalItems.markdown +++ b/content/draft4/validation/additionalItems.markdown @@ -24,3 +24,100 @@ related: - vocabulary: validation keyword: uniqueItems --- + +The [`additionalItems`]({{< ref "draft4/validation/additionalitems" >}}) +keyword restricts array instance items not described by the _sibling_ +[`items`]({{< ref "draft4/validation/items" >}}) keyword (when [`items`]({{< +ref "draft4/validation/items" >}}) is in array form), to validate against the +given subschema. + +{{}}This keyword **only** has an effect when the sibling +[`items`]({{< ref "draft4/validation/items" >}}) keyword is set to an array of +schemas. If [`items`]({{< ref "draft4/validation/items" >}}) is not present or +is set to a schema (not an array of schemas), [`additionalItems`]({{< ref +"draft4/validation/additionalitems" >}}) has no effect and is +ignored.{{}} + +{{}}This keyword does not prevent an array instance from being +empty or having fewer items than the [`items`]({{< ref +"draft4/validation/items" >}}) array. If needed, use the [`minItems`]({{< ref +"draft4/validation/minitems" >}}) keyword to assert on the minimum bounds of the +array.{{}} + +{{}} + +## Examples + +{{}} +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "items": [ { "type": "boolean" }, { "type": "number" } ], + "additionalItems": { "type": "string" } +} +{{}} + +{{}} +[ false, 35 ] +{{}} + +{{}} +[ false, 35, "foo", "bar" ] +{{}} + +{{}} +[ false, 35, { "foo": "bar" } ] +{{}} + +{{}} +[] +{{}} + +{{}} +"Hello World" +{{}} + +{{}} +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "items": [ { "type": "boolean" }, { "type": "number" } ], + "additionalItems": false +} +{{}} + +{{}} +[ false, 35 ] +{{}} + +{{}} +[ false, 35, "foo" ] +{{}} + +{{}} +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "items": { "type": "number" }, + "additionalItems": { "type": "string" } +} +{{}} + +{{}} +[ 1, 2, 3 ] +{{}} + +{{}} +[ 1, 2, "foo" ] +{{}} +{{}} +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "additionalItems": { "type": "string" } +} +{{}} + +{{}} +[ 1, 2, 3 ] +{{}} + +{{}} +"Hello World" +{{}} diff --git a/content/draft4/validation/additionalProperties.markdown b/content/draft4/validation/additionalProperties.markdown index 08b8672f..b34f365e 100644 --- a/content/draft4/validation/additionalProperties.markdown +++ b/content/draft4/validation/additionalProperties.markdown @@ -148,3 +148,123 @@ name.{{}} {{}} "Hello World" {{}} + +The [`additionalProperties`]({{< ref "draft4/validation/additionalproperties" +>}}) keyword restricts object instance properties not described by the +_sibling_ [`properties`]({{< ref "draft4/validation/properties" >}}) and +[`patternProperties`]({{< ref "draft4/validation/patternproperties" >}}) +keywords (if any), to validate against the given subschema. + +{{}}The use of the [`properties`]({{< ref +"draft4/validation/properties" >}}) keyword **does not prevent the presence of +other properties** in the object instance and **does not enforce the presence +of the declared properties**. In other words, additional data that is not +explicitly prohibited is permitted by default. This is intended behaviour to +ease schema evolution (open schemas are backwards compatible by default) and to +enable highly-expressive constraint-driven schemas. + +If you want to restrict instances to only contain the properties you declared, +you must set this keyword to the boolean schema `false`, and if you want to +enforce the presence of certain properties, you must use the [`required`]({{< +ref "draft4/validation/required" >}}) keyword accordingly. +{{}} + +{{}}While the most common use of this keyword is setting it to +the boolean schema `false` to prevent additional properties, it is possible to +set it to a satisfiable schema. Doing this, while omitting the +[`properties`]({{< ref "draft4/validation/properties" >}}) and +[`patternProperties`]({{< ref "draft4/validation/patternproperties" >}}) +keywords, is an elegant way of describing how the value of every property in +the object instance must look like independently of its +name.{{}} + +{{}} + +## Examples + +{{}} +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "properties": { + "foo": { "type": "string" } + }, + "patternProperties": { + "^x-": { "type": "integer" } + }, + "additionalProperties": false +} +{{}} + +{{}} +{ "foo": "bar", "x-test": 2 } +{{}} + +{{}} +{ "foo": "bar", "x-test": 2, "extra": true } +{{}} + +{{}} +{ "extra": true, "random": 1234 } +{{}} + +{{}} +{} +{{}} + +{{}} +"Hello World" +{{}} + +{{}} +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "additionalProperties": { "type": "integer" } +} +{{}} + +{{}} +{ "foo": 1, "bar": 2, "baz": 3 } +{{}} + +{{}} +{ "foo": 1, "name": "John Doe" } +{{}} + +{{}} +{} +{{}} + +{{}} +"Hello World" +{{}} + +{{}} +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "properties": { + "foo": { "type": "string" } + }, + "patternProperties": { + "^x-": { "type": "integer" } + }, + "additionalProperties": { + "type": "boolean" + } +} +{{}} + +{{}} +{ "foo": "bar", "x-test": 2, "extra": true } +{{}} + +{{}} +{ "foo": "bar", "x-test": 2, "extra": "should be a boolean" } +{{}} + +{{}} +{} +{{}} + +{{}} +"Hello World" +{{}} diff --git a/content/draft4/validation/allOf.markdown b/content/draft4/validation/allOf.markdown index c031b784..0075ff3a 100644 --- a/content/draft4/validation/allOf.markdown +++ b/content/draft4/validation/allOf.markdown @@ -139,3 +139,121 @@ result of this keyword given 3 subschemas: A, B, and C. {{}} "Hello World" {{}} + +The {{}} keyword restricts +instances to validate against _every_ given subschema. This keyword can be +thought of as a [logical +conjunction](https://en.wikipedia.org/wiki/Logical_conjunction) (AND) +operation, as instances are valid if they satisfy every constraint of every +subschema (the intersection of the constraints). + +{{}} Note that in JSON Schema [Draft 7](/draft7) and earlier +versions, any subschema declaring the `$ref` keyword is considered to be a +_reference object_ and any other sibling keyword will be silently ignored. To +avoid this, wrap subschemas with references that make use of other keywords +using the [`allOf`]({{< ref "draft4/validation/allOf" >}}) keyword. {{}} + +{{}}This keyword typically has a single use case: combining one +or more schemas through the use of (internal or external) references. If this +is not the case, prefer elevating the keywords of every subschema to the outer +schema and avoid using this keyword. {{}} + +This keyword is equivalent to the `&&` operator found in most programming +languages. For example: + +```c +bool valid = A && B && C; +``` + +As a reference, the following boolean [truth +table](https://en.wikipedia.org/wiki/Truth_table) considers the evaluation +result of this keyword given 3 subschemas: A, B, and C. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
allOfSubschema ASubschema BSubschema C
Invalid Invalid Invalid Invalid
Invalid Invalid Invalid Valid
Invalid Invalid Valid Invalid
Invalid Invalid Valid Valid
Invalid Valid Invalid Invalid
Invalid Valid Invalid Valid
Invalid Valid Valid Invalid
Valid Valid Valid Valid
+ +## Examples + +{{}} +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "allOf": [ + { "$ref": "#/definitions/foo" }, + { "$ref": "#/definitions/bar" } + ], + "definitions": { + "foo": { "type": "number" }, + "bar": { "type": "integer" } + } +} +{{}} + +{{}} +12345 +{{}} + +{{}} +3.14 +{{}} + +{{}} +"Hello World" +{{}} diff --git a/content/draft4/validation/anyOf.markdown b/content/draft4/validation/anyOf.markdown index 3307a60d..b1957693 100644 --- a/content/draft4/validation/anyOf.markdown +++ b/content/draft4/validation/anyOf.markdown @@ -19,3 +19,111 @@ related: - vocabulary: validation keyword: not --- + +The [`anyOf`]({{< ref "draft4/validation/anyof" >}}) keyword restricts +instances to validate against _at least one_ (but potentially multiple) of the +given subschemas. This keyword represents a [logical +disjunction](https://en.wikipedia.org/wiki/Logical_disjunction) (OR) +operation, as instances are valid if they satisfy the constraints of one or +more subschemas (the union of the constraints). + + +This keyword is equivalent to the `||` operator found in most programming +languages. For example: + +```c +bool valid = A || B || C; +``` + +As a reference, the following boolean [truth +table](https://en.wikipedia.org/wiki/Truth_table) considers the evaluation +result of this keyword given 3 subschemas: A, B, and C. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
anyOfSubschema ASubschema BSubschema C
Invalid Invalid Invalid Invalid
Valid Invalid Invalid Valid
Valid Invalid Valid Invalid
Valid Invalid Valid Valid
Valid Valid Invalid Invalid
Valid Valid Invalid Valid
Valid Valid Valid Invalid
Valid Valid Valid Valid
+ +## Examples + +{{}} +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "anyOf": [ + { "required": [ "foo" ] }, + { "required": [ "bar" ] } + ] +} +{{}} + +{{}} +{ "foo": 1 } +{{}} + +{{}} +{ "bar": 2 } +{{}} + +{{}} +{ "foo": 1, "bar": 2 } +{{}} + +{{}} +{ "extra": 4 } +{{}} diff --git a/content/draft4/validation/default.markdown b/content/draft4/validation/default.markdown index 497e63e3..1388ccf4 100644 --- a/content/draft4/validation/default.markdown +++ b/content/draft4/validation/default.markdown @@ -17,3 +17,92 @@ related: - vocabulary: validation keyword: description --- + + +The [`default`]({{< ref "draft4/validation/default" >}}) keyword declares a +default instance value for a schema or any of its subschemas, typically to +support specialised tooling like documentation and form generators. This +keyword is merely descriptive and does not affect validation. + +{{}} + +The standard evaluation process will not automatically use these values to fill +in missing parts of the instance. Furthermore, the JSON Schema specification +does not provide any guidance on how this keyword should be used. + +Consult the documentation of any JSON Schema tooling you rely on to check if +and how it makes use of this keyword. + +{{}} + +{{}} + +Meta-schema validation will not check that the default values you declare are +actually valid against their respective schemas, as JSON Schema does not offer +a mechanism for meta-schemas to declare that instances validate against parts +of the same instance being evaluated. As a consequence, it is not rare for +schemas to declare invalid default values that go undetected for a long time. + +It is recommended to use the [`jsonschema +lint`](https://github.com/sourcemeta/jsonschema/blob/main/docs/lint.markdown) +command, as this linter performs further checks to detect many corner cases, +including this one. + +{{}} + +## Examples + +{{}} +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "type": "object", + "default": {}, + "properties": { + "language": { "default": "en" }, + "notifications": { "default": true } + } +} +{{}} + +{{}} +{ "language": "es", "notifications": false } +{{}} + +{{}} +{} +{{}} + +{{}} +"Hello World" +{{}} + +{{}} +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "properties": { + "email": { + "default": "johndoe@acme.com", + "$ref": "#/definitions/email-address" + } + }, + "definitions": { + "email-address": { + "type": "string", + "format": "email", + "default": "example@example.org" + } + } +} +{{}} + +{{}} +{ "email": "jane@foo.com" } +{{}} + +{{}} +{} +{{}} + +{{}} +{ "email": 1 } +{{}} diff --git a/content/draft4/validation/definitions.markdown b/content/draft4/validation/definitions.markdown index 2f66a819..b1d0ad66 100644 --- a/content/draft4/validation/definitions.markdown +++ b/content/draft4/validation/definitions.markdown @@ -17,3 +17,62 @@ related: - vocabulary: core keyword: $ref --- + + +The [`definitions`]({{< ref "draft4/validation/definitions" >}}) keyword is a +container for storing reusable schemas within a schema resource, which can be +referenced using the [`$ref`]({{< ref "draft4/core/ref" >}}) keyword. From a +software engineering point of view, this keyword is analogous to defining +_internal_ helper functions as part of a larger program. + +{{}} + +Use this keyword to reduce duplication of internal declarations within a +schema. However, **prefer extracting standalone entities that represent more +than just internal helpers into separate schema files**, and externally +referencing them instead. Otherwise, you will end up with big monolithic +schemas that are challenging to understand and maintain. + +If you need to resolve external references in advance (for distribution or +analysis), look at the [`jsonschema +bundle`](https://github.com/sourcemeta/jsonschema/blob/main/docs/bundle.markdown) +command. + +{{}} + +{{}} + +This keyword declares helper schemas for use _within_ the same schema file or +resource. Defining schema files or resources that use this keyword (and +typically no other keyword) to group common definitions for _other_ schema +files or resources to reference is considered to be an anti-pattern. If you +want to share a schema across multiple schema files or resources, that common +schema should be a standalone schema file or resource itself. + +{{}} + +## Examples + +{{}} +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "properties": { + "firstName": { "$ref": "#/definitions/nonEmptyString" }, + "lastName": { "$ref": "#/definitions/nonEmptyString" } + }, + "definitions": { + "nonEmptyString": { + "type": "string", + "minLength": 1 + } + } +} +{{}} + +{{}} +{ "firstName": "John", "lastName": "Doe" } +{{}} + +{{}} +{ "firstName": "", "lastName": "" } +{{}} diff --git a/content/draft4/validation/dependencies.markdown b/content/draft4/validation/dependencies.markdown index 45699e03..b0786d1d 100644 --- a/content/draft4/validation/dependencies.markdown +++ b/content/draft4/validation/dependencies.markdown @@ -19,3 +19,206 @@ related: - vocabulary: validation keyword: required --- + + +The [`dependencies`]({{< ref "draft4/validation/dependencies" >}}) keyword is +used to express property-based constraints on object instances. It has two +different modes of operation depending on the type of each dependency value: + +- **Property Dependencies (Array)**: When a dependency value is set to an array + of strings, [`dependencies`]({{< ref "draft4/validation/dependencies" >}}) + restricts object instances to define certain properties if the corresponding + property key is also defined. + +- **Schema Dependencies (Schema)**: When a dependency value is set to a schema, + [`dependencies`]({{< ref "draft4/validation/dependencies" >}}) restricts + object instances to validate against the given subschema if the corresponding + property key is defined. Note that the given subschema is evaluated against + the object that defines the property dependency. + +{{}} Note that multiple potentially interrelated dependencies +can be declared at once, in which case every dependency must be transitively +fulfilled for the object instance to be valid. For example, if a schema marks +the property `B` as required if the property `A` is present and also marks the +property `C` as required if the property `B` is present, defining the property +`A` transitively requires _both_ the `B` and `C` properties to be present in +the object instance. {{}} + +{{}} + +## Examples + +{{}} +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "dependencies": { + "foo": [ "bar", "baz" ] + } +} +{{}} + +{{}} +{ "foo": 1, "bar": 2, "baz": 3 } +{{}} + +{{}} +{ "foo": 1, "bar": 2 } +{{}} + +{{}} +{ "foo": 1 } +{{}} + +{{}} +{ "qux": 4 } +{{}} + +{{}} +{} +{{}} + +{{}} +"Hello World" +{{}} + +{{}} +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "dependencies": { + "foo": [ "bar" ], + "bar": [ "baz" ] + } +} +{{}} + +{{}} +{ "foo": 1, "bar": 2, "baz": 3 } +{{}} + +{{}} +{ "foo": 1, "bar": 2 } +{{}} + +{{}} +{ "bar": 2, "baz": 3 } +{{}} + +{{}} +{} +{{}} + +{{}} +"Hello World" +{{}} + +{{}} +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "dependencies": { + "foo": { "maxProperties": 2 } + } +} +{{}} + +{{}} +{ "foo": 1, "bar": 2 } +{{}} + +{{}} +{ "foo": 1, "bar": 2, "baz": 3 } +{{}} + +{{}} +{ "firstName": "John", "lastName": "Doe", "age": 50 } +{{}} + +{{}} +{} +{{}} + +{{}} +"Hello World" +{{}} + +{{}} +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "dependencies": { + "foo": { "maxProperties": 2 }, + "bar": { "minProperties": 2 } + } +} +{{}} + +{{}} +{ "foo": 1, "bar": 2 } +{{}} + +{{}} +{ "foo": 1, "bar": 2, "extra": true } +{{}} + +{{}} +{ "foo": 1 } +{{}} + +{{}} +{ "foo": 1, "name": "John Doe", "age": 50 } +{{}} + +{{}} +{ "bar": 2 } +{{}} + +{{}} +{} +{{}} + +{{}} +"Hello World" +{{}} + +{{}} +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "dependencies": { + "creditCard": [ "billingAddress" ], + "billingAddress": { "required": [ "street", "city", "zipcode" ] } + } +} +{{}} + +{{}} +{ + "creditCard": "1234-5678-9012-3456", + "billingAddress": { + "street": "123 Main St", + "city": "Anytown", + "zipcode": "12345" + } +} +{{}} + +{{}} +{ "creditCard": "1234-5678-9012-3456" } +{{}} + +{{}} +{ + "billingAddress": { + "street": "123 Main St" + } +} +{{}} + +{{}} +{ "name": "John Doe" } +{{}} + +{{}} +{} +{{}} + +{{}} +"Hello World" +{{}} diff --git a/content/draft4/validation/description.markdown b/content/draft4/validation/description.markdown index 816a359f..60a3a946 100644 --- a/content/draft4/validation/description.markdown +++ b/content/draft4/validation/description.markdown @@ -15,3 +15,82 @@ related: - vocabulary: validation keyword: default --- + + +The [`description`]({{< ref "draft4/validation/description" >}}) keyword is a +placeholder for a longer human-readable string summary of what a schema or any +of its subschemas are about. This keyword is merely descriptive and does not +affect validation. + +{{}} + +We heavily recommend to declare this keyword at the top level of every schema, +as a human-readable longer description of what the schema is about. +Note that this keyword is meant to be to be used in conjunction with the +[`title`]({{< ref "draft4/validation/title" >}}) keyword. The idea is to +augment the short summary with a longer description, and not to avoid the +concise summary altogether. + +{{}} + +{{}} + +Tooling makers must be careful when statically traversing schemas in search of +occurrences of this keyword. It is possible for schemas to make use of this +keyword behind conditional operators, references, or any other type of keyword +that makes it hard or even impossible to correctly locate these values in all +cases. + +{{}} + +## Examples + +{{}} +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "title": "Even Number", + "description": "This schema describes an even number", + "type": "number", + "multipleOf": 2 +} +{{}} + +{{}} +10 +{{}} + +{{}} +7 +{{}} + +{{}} +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "title": "Number", + "type": "number", + "anyOf": [ + { + "description": "This is an even number", + "multipleOf": 2 + }, + { + "description": "This is an odd number", + "not": { + "multipleOf": 2 + } + } + ] +} +{{}} + +{{}} +10 +{{}} + +{{}} +7 +{{}} + +{{}} +"Hello World" +{{}} diff --git a/content/draft4/validation/enum.markdown b/content/draft4/validation/enum.markdown index 8c513f8d..1426a560 100644 --- a/content/draft4/validation/enum.markdown +++ b/content/draft4/validation/enum.markdown @@ -19,3 +19,76 @@ related: - vocabulary: validation keyword: oneOf --- + + +The [`enum`]({{< ref "draft4/validation/enum" >}}) keyword restricts instances +to a finite set of possible values, which may be of different types. + +{{}} Constraining instances to a set of possible values by +definition implies the given JSON types. Therefore, combining this keyword with +the [`type`]({{< ref "draft4/validation/type" >}}) keyword is redundant (or +even invalid if types don't agree), and considered an +anti-pattern.{{}} + +## Examples + +{{}} +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "enum": [ "red", "green", "blue" ] +} +{{}} + +{{}} +"green" +{{}} + +{{}} +"black" +{{}} + +{{}} +2 +{{}} + +{{}} +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "enum": [ 1, 2.0, 3 ] +} +{{}} + +{{}} +1 +{{}} + +{{}} +2 +{{}} + +{{}} +5 +{{}} + +{{}} +"Hello" +{{}} + +{{}} +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "enum": [ "red", 123, true, { "foo": "bar" }, [ 1, 2 ], null ] +} +{{}} + +{{}} +true +{{}} + +{{}} +{ "foo": "bar" } +{{}} + +{{}} +{ "foo": "baz" } +{{}} diff --git a/content/draft4/validation/exclusiveMaximum.markdown b/content/draft4/validation/exclusiveMaximum.markdown index 33338463..f6de1bed 100644 --- a/content/draft4/validation/exclusiveMaximum.markdown +++ b/content/draft4/validation/exclusiveMaximum.markdown @@ -3,7 +3,6 @@ keyword: "exclusiveMaximum" signature: "Boolean" value: This keyword must be set to a boolean value summary: "When [`maximum`](/draft4/validation/maximum) is present and this keyword is set to true, the numeric instance must be less than the value in [`maximum`](/draft4/validation/maximum)." -summary: "Validation succeeds if the numeric instance is less than the given number." kind: [ "assertion" ] instance: [ "number" ] specification: "https://json-schema.org/draft-04/draft-fge-json-schema-validation-00#rfc.section.5.1.2" @@ -29,3 +28,90 @@ related: - vocabulary: validation keyword: multipleOf --- + +The [`exclusiveMaximum`]({{< ref "draft4/validation/exclusivemaximum" >}}) +keyword is a boolean modifier for the [`maximum`]({{< ref +"draft4/validation/maximum" >}}) keyword. When set to `true`, it changes the +validation behavior of the [`maximum`]({{< ref "draft4/validation/maximum" >}}) +keyword from _less than or equal to_ to _strictly less than_. This keyword has +no effect if the [`maximum`]({{< ref "draft4/validation/maximum" >}}) keyword +is not present in the same schema. + +{{}} + +## Examples + +{{}} +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "maximum": 10, + "exclusiveMaximum": true +} +{{}} + +{{}} +9.9 +{{}} + +{{}} +9 +{{}} + +{{}} +10.001 +{{}} + +{{}} +11 +{{}} + +{{}} +10.0 +{{}} + +{{}} +10 +{{}} + +{{}} +"100000" +{{}} + +{{}} +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "exclusiveMaximum": true +} +{{}} + +{{}} +10 +{{}} + +{{}} +999999999 +{{}} + +{{}} +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "maximum": 10, + "exclusiveMaximum": false +} +{{}} + +{{}} +10 +{{}} + +{{}} +10.0 +{{}} + +{{}} +9.9 +{{}} + +{{}} +10.1 +{{}} diff --git a/content/draft4/validation/exclusiveMinimum.markdown b/content/draft4/validation/exclusiveMinimum.markdown index d0187514..08ab320d 100644 --- a/content/draft4/validation/exclusiveMinimum.markdown +++ b/content/draft4/validation/exclusiveMinimum.markdown @@ -28,3 +28,90 @@ related: - vocabulary: validation keyword: multipleOf --- + +The [`exclusiveMinimum`]({{< ref "draft4/validation/exclusiveminimum" >}}) +keyword is a boolean modifier for the [`minimum`]({{< ref +"draft4/validation/minimum" >}}) keyword. When set to `true`, it changes the +validation behavior of the [`minimum`]({{< ref "draft4/validation/minimum" >}}) +keyword from _greater than or equal to_ to _strictly greater than_. This +keyword has no effect if the [`minimum`]({{< ref "draft4/validation/minimum" +>}}) keyword is not present in the same schema. + +{{}} + +## Examples + +{{}} +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "minimum": 10, + "exclusiveMinimum": true +} +{{}} + +{{}} +10.1 +{{}} + +{{}} +11 +{{}} + +{{}} +9.9 +{{}} + +{{}} +9 +{{}} + +{{}} +10.0 +{{}} + +{{}} +10 +{{}} + +{{}} +"100000" +{{}} + +{{}} +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "exclusiveMinimum": true +} +{{}} + +{{}} +10 +{{}} + +{{}} +-999999999 +{{}} + +{{}} +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "minimum": 10, + "exclusiveMinimum": false +} +{{}} + +{{}} +10 +{{}} + +{{}} +10.0 +{{}} + +{{}} +10.1 +{{}} + +{{}} +9.9 +{{}} diff --git a/content/draft4/validation/format.markdown b/content/draft4/validation/format.markdown index e06494dd..3b5c3d55 100644 --- a/content/draft4/validation/format.markdown +++ b/content/draft4/validation/format.markdown @@ -14,3 +14,69 @@ index: 97 changed_in: - draft3 --- + + +The [`format`]({{< ref "draft4/validation/format" >}}) keyword communicates +that string instances are of the given logical type. + +{{}} By default, this keyword does not perform validation, as +validating formats is considered optional by the official JSON Schema Test +Suite. As a consequence, not many implementations support it. If validation is +desired, the best practice is to combine this keyword with the [`pattern`]({{< ref "draft4/validation/pattern" >}}) keyword. This guarantees interoperable +and unambiguous behavior across JSON Schema implementations. +{{}} + +{{}} While [technically +allowed](https://json-schema.org/draft-04/draft-fge-json-schema-validation-00#rfc.section.7) +by the JSON Schema specification, extending this keyword with custom formats is +considered to be an anti-pattern that can introduce interoperability issues and +undefined behavior. As a best practice, stick to standardised formats. If +needed, introduce a new keyword for custom string logical +types.{{}} + +{{}} This keyword and its validation guarantees are a common +source of confusion of the JSON Schema specification across versions. + +Since the introduction of this keyword, the JSON Schema specifications +clarified that validation was not mandatory. However, the majority of older +Schema implementations did support validation, leading schema-writers to rely +on it. At the same time, a second problem emerged: implementations often didn't +agree on the strictness of validation, mainly on complex logical types like +e-mail addresses, leading to various interoperability issues. + +To avoid the gray areas of this keyword, we recommend only treating it as +semantic metadata, never enabling validation support at the implementation +level (even if supported), and performing validation using the [`pattern`]({{< +ref "draft4/validation/pattern" >}}) keyword. {{}} + +The supported formats are the following. + +| Format | Category | Specification | +|-------------------|----------------------|---------------| +| `"date-time"` | Time | [JSON Schema Draft 4 Validation Section 7.3.1](https://json-schema.org/draft-04/draft-fge-json-schema-validation-00#rfc.section.7.3.1) | +| `"email"` | Emails | [JSON Schema Draft 4 Validation Section 7.3.2](https://json-schema.org/draft-04/draft-fge-json-schema-validation-00#rfc.section.7.3.2) | +| `"hostname"` | Hostnames | [JSON Schema Draft 4 Validation Section 7.3.3](https://json-schema.org/draft-04/draft-fge-json-schema-validation-00#rfc.section.7.3.3) | +| `"ipv4"` | IP Addresses | [JSON Schema Draft 4 Validation Section 7.3.4](https://json-schema.org/draft-04/draft-fge-json-schema-validation-00#rfc.section.7.3.4) | +| `"ipv6"` | IP Addresses | [JSON Schema Draft 4 Validation Section 7.3.5](https://json-schema.org/draft-04/draft-fge-json-schema-validation-00#rfc.section.7.3.5) | +| `"uri"` | Resource Identifiers | [JSON Schema Draft 4 Validation Section 7.3.6](https://json-schema.org/draft-04/draft-fge-json-schema-validation-00#rfc.section.7.3.6) | + +## Examples + +{{}} +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "format": "email" +} +{{}} + +{{}} +"john.doe@example.com" +{{}} + +{{}} +"foo-bar" +{{}} + +{{}} +45 +{{}} diff --git a/content/draft4/validation/items.markdown b/content/draft4/validation/items.markdown index d7e49555..b6c6bba5 100644 --- a/content/draft4/validation/items.markdown +++ b/content/draft4/validation/items.markdown @@ -29,3 +29,108 @@ related: - vocabulary: validation keyword: uniqueItems --- + + +The [`items`]({{< ref "draft4/validation/items" >}}) keyword is used to +validate array items and has two different modes of operation depending on the +type of its value: + +- **Schema**: When set to a schema, [`items`]({{< ref "draft4/validation/items" + >}}) validates that all items in the array instance validate against the + given subschema. + +- **Array**: When set to an array of schemas, [`items`]({{< ref + "draft4/validation/items" >}}) validates each item in the array instance + against the subschema at the corresponding position. Items beyond the length + of the [`items`]({{< ref "draft4/validation/items" >}}) array can be + validated using the [`additionalItems`]({{< ref + "draft4/validation/additionalitems" >}}) keyword. + +{{}}This keyword does not prevent an array instance from being +empty. If needed, use the [`minItems`]({{< ref "draft4/validation/minitems" >}}) to assert on the minimum bounds of the array.{{}} + +{{}} + +## Examples + +{{}} +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "items": { "type": "number" } +} +{{}} + +{{}} +[ 1, -3.4, 54 ] +{{}} + +{{}} +[] +{{}} + +{{}} +[ 1, -3.4, 54, "foo" ] +{{}} + +{{}} +"Hello World" +{{}} + +{{}} +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "items": [ { "type": "boolean" }, { "type": "number" } ] +} +{{}} + +{{}} +[ false, 35 ] +{{}} + +{{}} +[ false, 35, "foo", "bar" ] +{{}} + +{{}} +[ "not a boolean", 35 ] +{{}} + +{{}} +[ false, "not a number" ] +{{}} + +{{}} +[] +{{}} + +{{}} +"Hello World" +{{}} + +{{}} +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "items": [ { "type": "boolean" }, { "type": "number" } ], + "additionalItems": { "type": "string" } +} +{{}} + +{{}} +[ false, 35 ] +{{}} + +{{}} +[ false, 35, "foo", "bar" ] +{{}} + +{{}} +[ false, 35, { "foo": "bar" } ] +{{}} + +{{}} +[] +{{}} + +{{}} +"Hello World" +{{}} diff --git a/content/draft4/validation/maxItems.markdown b/content/draft4/validation/maxItems.markdown index 790864cf..0d088262 100644 --- a/content/draft4/validation/maxItems.markdown +++ b/content/draft4/validation/maxItems.markdown @@ -19,3 +19,42 @@ related: - vocabulary: validation keyword: minItems --- + + +The [`maxItems`]({{< ref "draft4/validation/maxitems" >}}) keyword restricts array instances to consists of an inclusive +maximum numbers of items. + +{{}} The presence of this keyword does not depend on the +presence of the [`items`]({{< ref "draft4/validation/items" >}}) keyword. +{{}} + +{{}}To restrict array instances to the empty array, prefer using +the [`enum`]({{< ref "draft4/validation/enum" >}}) keyword with a single empty +array value instead of setting this keyword to `0`. {{}} + +{{}} + +## Examples + +{{}} +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "maxItems": 3 +} +{{}} + +{{}} +[ 1, 2, 3, 4 ] +{{}} + +{{}} +[ 1, true, "hello" ] +{{}} + +{{}} +[ false, "foo" ] +{{}} + +{{}} +"Hello World" +{{}} diff --git a/content/draft4/validation/maxLength.markdown b/content/draft4/validation/maxLength.markdown index 7449b6c1..7f6705e3 100644 --- a/content/draft4/validation/maxLength.markdown +++ b/content/draft4/validation/maxLength.markdown @@ -19,3 +19,57 @@ related: - vocabulary: validation keyword: format --- + + +The [`maxLength`]({{< ref "draft4/validation/maxlength" >}}) keyword restricts string instances to consists of an inclusive +maximum number of [Unicode](https://unicode.org) code-points (logical +characters), which is not necessarily the same as the number of bytes in the +string. + +{{}} While the [IETF RFC +8259](https://www.rfc-editor.org/rfc/rfc8259) JSON standard recommends the use +of [UTF-8](https://en.wikipedia.org/wiki/UTF-8), other Unicode encodings are +permitted. Therefore a JSON string may be represented in up to 4x the number of +bytes as its number of code-points (assuming +[UTF-32](https://en.wikipedia.org/wiki/UTF-32) as the upper bound). + +JSON Schema does not provide a mechanism to assert on the byte size of a JSON +string, as this is an implementation-dependent property of the JSON parser in +use. {{}} + +{{}} Be careful when making use of this keyword to +inadvertently assert on the byte length of JSON strings before inserting them +into byte-sensitive destinations like fixed-size buffers. Always assume that +the byte length of a JSON string can arbitrary larger that the number of +logical characters.{{}} + +{{}}To restrict string instances to the empty string, prefer +using the [`enum`]({{< ref "draft4/validation/enum" >}}) keyword with a single +empty string value instead of setting this keyword to `0`. {{}} + +{{}} + +## Examples + +{{}} +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "maxLength": 3 +} +{{}} + +{{}} +"foo" +{{}} + +{{}} +"こんにちは" +{{}} + +{{}} +"hi" +{{}} + +{{}} +55 +{{}} diff --git a/content/draft4/validation/maxProperties.markdown b/content/draft4/validation/maxProperties.markdown index bbfbc6a3..3389e71b 100644 --- a/content/draft4/validation/maxProperties.markdown +++ b/content/draft4/validation/maxProperties.markdown @@ -21,3 +21,42 @@ related: - vocabulary: validation keyword: additionalProperties --- + + +The [`maxProperties`]({{< ref "draft4/validation/maxproperties" >}}) keyword restricts object instances to consists of an +inclusive maximum numbers of properties. + +{{}} The presence of this keyword does not depend on the +presence of the [`properties`]({{< ref "draft4/validation/properties" >}}) +keyword. {{}} + +{{}}To restrict object instances to the empty object, prefer +using the [`enum`]({{< ref "draft4/validation/enum" >}}) keyword with a single +empty object value instead of setting this keyword to `0`. {{}} + +{{}} + +## Examples + +{{}} +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "maxProperties": 2 +} +{{}} + +{{}} +{ "foo": 1, "bar": 2, "baz": 3 } +{{}} + +{{}} +{ "foo": 1, "bar": 2 } +{{}} + +{{}} +{ "foo": 1 } +{{}} + +{{}} +"Hello World" +{{}} diff --git a/content/draft4/validation/maximum.markdown b/content/draft4/validation/maximum.markdown index 251400da..4e1a6f99 100644 --- a/content/draft4/validation/maximum.markdown +++ b/content/draft4/validation/maximum.markdown @@ -24,3 +24,77 @@ related: - vocabulary: validation keyword: multipleOf --- + + +The [`maximum`]({{< ref "draft4/validation/maximum" >}}) keyword restricts number instances to be less than or equal to +the given number. + +{{}} + +## Examples + +{{}} +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "maximum": 10 +} +{{}} + +{{}} +9.9 +{{}} + +{{}} +9 +{{}} + +{{}} +10.001 +{{}} + +{{}} +11 +{{}} + +{{}} +10.0 +{{}} + +{{}} +10 +{{}} + +{{}} +"100000" +{{}} + +{{}} +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "maximum": -2.1 +} +{{}} + +{{}} +-2.2 +{{}} + +{{}} +-3 +{{}} + +{{}} +-2.01 +{{}} + +{{}} +-2 +{{}} + +{{}} +-2.1 +{{}} + +{{}} +"100000" +{{}} diff --git a/content/draft4/validation/minItems.markdown b/content/draft4/validation/minItems.markdown index 28044bae..c5a537f0 100644 --- a/content/draft4/validation/minItems.markdown +++ b/content/draft4/validation/minItems.markdown @@ -21,3 +21,38 @@ related: - vocabulary: validation keyword: maxItems --- + + +The [`minItems`]({{< ref "draft4/validation/minitems" >}}) keyword restricts array instances to consists of an inclusive +minimum numbers of items. + +{{}} The presence of this keyword does not depend on the +presence of the [`items`]({{< ref "draft4/validation/items" >}}) keyword. +{{}} + +{{}} + +## Examples + +{{}} +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "minItems": 3 +} +{{}} + +{{}} +[ 1, 2, 3, 4 ] +{{}} + +{{}} +[ 1, true, "hello" ] +{{}} + +{{}} +[ false, "foo" ] +{{}} + +{{}} +"Hello World" +{{}} diff --git a/content/draft4/validation/minLength.markdown b/content/draft4/validation/minLength.markdown index b7d13e30..45869ef2 100644 --- a/content/draft4/validation/minLength.markdown +++ b/content/draft4/validation/minLength.markdown @@ -21,3 +21,46 @@ related: - vocabulary: validation keyword: format --- + + +The [`minLength`]({{< ref "draft4/validation/minlength" >}}) keyword restricts string instances to consists of an inclusive +minimum number of [Unicode](https://unicode.org) code-points (logical +characters), which is not necessarily the same as the number of bytes in the +string. + +{{}} While the [IETF RFC +8259](https://www.rfc-editor.org/rfc/rfc8259) JSON standard recommends the use +of [UTF-8](https://en.wikipedia.org/wiki/UTF-8), other Unicode encodings are +permitted. Therefore a JSON string may be represented in more bytes than its +number of code-points. + +JSON Schema does not provide a mechanism to assert on the byte size of a JSON +string, as this is an implementation-dependent property of the JSON parser in +use. {{}} + +{{}} + +## Examples + +{{}} +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "minLength": 3 +} +{{}} + +{{}} +"foo" +{{}} + +{{}} +"こんにちは" +{{}} + +{{}} +"hi" +{{}} + +{{}} +55 +{{}} diff --git a/content/draft4/validation/minProperties.markdown b/content/draft4/validation/minProperties.markdown index 7793e4e6..44f5474e 100644 --- a/content/draft4/validation/minProperties.markdown +++ b/content/draft4/validation/minProperties.markdown @@ -23,3 +23,38 @@ related: - vocabulary: validation keyword: additionalProperties --- + + +The [`minProperties`]({{< ref "draft4/validation/minproperties" >}}) keyword restricts object instances to consists of an +inclusive minimum numbers of properties. + +{{}} The presence of this keyword does not depend on the +presence of the [`properties`]({{< ref "draft4/validation/properties" >}}) +keyword. {{}} + +{{}} + +## Examples + +{{}} +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "minProperties": 2 +} +{{}} + +{{}} +{ "foo": 1, "bar": 2, "baz": 3 } +{{}} + +{{}} +{ "foo": 1, "bar": 2 } +{{}} + +{{}} +{ "foo": 1 } +{{}} + +{{}} +"Hello World" +{{}} diff --git a/content/draft4/validation/minimum.markdown b/content/draft4/validation/minimum.markdown index e2727913..10b2b091 100644 --- a/content/draft4/validation/minimum.markdown +++ b/content/draft4/validation/minimum.markdown @@ -24,3 +24,77 @@ related: - vocabulary: validation keyword: multipleOf --- + + +The [`minimum`]({{< ref "draft4/validation/minimum" >}}) keyword restricts number instances to be greater than or equal to +the given number. + +{{}} + +## Examples + +{{}} +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "minimum": 10 +} +{{}} + +{{}} +10.1 +{{}} + +{{}} +11 +{{}} + +{{}} +9.9 +{{}} + +{{}} +9 +{{}} + +{{}} +10.0 +{{}} + +{{}} +10 +{{}} + +{{}} +"100000" +{{}} + +{{}} +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "minimum": -2.1 +} +{{}} + +{{}} +-2.09 +{{}} + +{{}} +-2 +{{}} + +{{}} +-2.11 +{{}} + +{{}} +-3 +{{}} + +{{}} +-2.1 +{{}} + +{{}} +"100000" +{{}} diff --git a/content/draft4/validation/multipleOf.markdown b/content/draft4/validation/multipleOf.markdown index c807c506..fd64882b 100644 --- a/content/draft4/validation/multipleOf.markdown +++ b/content/draft4/validation/multipleOf.markdown @@ -23,3 +23,111 @@ related: - vocabulary: validation keyword: minimum --- + + +The [`multipleOf`]({{< ref "draft4/validation/multipleof" >}}) keyword +restricts number instances to be multiples of the given number. Note that the +number `0` is a multiple of every number, as for every number `k`, the +multiplication `0 * k` yield an integer value (in this case always 0). This case +is not to be confused with [division by +zero](https://en.wikipedia.org/wiki/Division_by_zero), which is not a permitted +operation in most computer systems. + +{{}}Setting this keyword to negative powers of 10, such as +`0.01` (10^-2), `0.001` (10^-3), and `0.0001` (10^-4), is a common mechanism to +control the maximum number of digits in the fractional part of a real number. +For example, `1.2` and `-12.34` are multiples of `0.01`, but `1.234` is +not.{{}} + +{{}} + +## Examples + +{{}} +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "multipleOf": 5 +} +{{}} + +{{}} +10 +{{}} + +{{}} +-5 +{{}} + +{{}} +15.0 +{{}} + +{{}} +8 +{{}} + +{{}} +0 +{{}} + +{{}} +"100000" +{{}} + +{{}} +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "multipleOf": 2.3 +} +{{}} + +{{}} +6.9 +{{}} + +{{}} +-4.6 +{{}} + +{{}} +2.4 +{{}} + +{{}} +0 +{{}} + +{{}} +"100000" +{{}} + +{{}} +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "multipleOf": 0.01 +} +{{}} + +{{}} +2 +{{}} + +{{}} +5.1 +{{}} + +{{}} +-12.34 +{{}} + +{{}} +1.234 +{{}} + +{{}} +0 +{{}} + +{{}} +"100000" +{{}} diff --git a/content/draft4/validation/not.markdown b/content/draft4/validation/not.markdown index 4d2c6b03..c17db5ad 100644 --- a/content/draft4/validation/not.markdown +++ b/content/draft4/validation/not.markdown @@ -21,3 +21,59 @@ related: - vocabulary: validation keyword: oneOf --- + + +The [`not`]({{< ref "draft4/validation/not" >}}) keyword restricts +instances to fail validation against the given subschema. This keyword +represents a [logical negation](https://en.wikipedia.org/wiki/Negation) (NOT) +operation. In other words, the instance successfully validates against the +schema only if it does not match the given subschema. + + +{{}} Avoid the use of this keyword (usually negating the +[`required`]({{< ref "draft4/validation/required" >}}) keyword) to prohibit +specific object properties from being defined. Instead, use the +[`properties`]({{< ref "draft4/validation/properties" >}}) keyword and set +the disallowed object properties to the `false` boolean +schema.{{}} + +This keyword is equivalent to the `!` operator found in most programming +languages. For example: + +```c +bool valid = !not_schema; +``` + +## Examples + +{{}} +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "not": { + "const": "Prohibited" + } +} +{{}} + +{{}} +"Hello World" +{{}} + +{{}} +"Prohibited" +{{}} + +{{}} +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "not": { + "type": "string", + "minLength": 10, + "maxLength": 9 + } +} +{{}} + +{{}} +"Hello World" +{{}} diff --git a/content/draft4/validation/oneOf.markdown b/content/draft4/validation/oneOf.markdown index 97358323..bd3153ce 100644 --- a/content/draft4/validation/oneOf.markdown +++ b/content/draft4/validation/oneOf.markdown @@ -19,3 +19,129 @@ related: - vocabulary: validation keyword: not --- + + +The [`oneOf`]({{< ref "draft4/validation/oneof" >}}) keyword restricts +instances to validate against _exactly one_ (and only one) of the given +subschemas and fail on the rest. This keyword represents a [logical exclusive +disjunction](https://en.wikipedia.org/wiki/Exclusive_or) (XOR) operation. In +practice, the vast majority of schemas don't require exclusive disjunction +semantics but a simple disjunction. If you are not sure, the [`anyOf`]({{< ref +"draft4/validation/anyof" >}}) keyword is probably a better fit. + +{{}} + +Avoid this keyword unless you absolutely need exclusive disjunction +semantics, which is rarely the case. As its name implies, this keyword +enforces the instance to be valid against **only one of its subschemas**. +Therefore, a JSON Schema implementation will exhaustively evaluate every +subschema to make sure the rest fails, potentially introducing unnecessary +computational overhead. + +{{}} + +This keyword is equivalent to the following complex boolean construct that +combines the `||`, `&&`, and `!` operators found in most programming +languages: + +```c +bool valid = (A && !B && !C) || (!A && B && !C) || (!A && !B && C); +``` + +As a reference, the following boolean [truth +table](https://en.wikipedia.org/wiki/Truth_table) considers the evaluation +result of this keyword given 3 subschemas: A, B, and C. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
oneOfSubschema ASubschema BSubschema C
Invalid Invalid Invalid Invalid
Valid Invalid Invalid Valid
Valid Invalid Valid Invalid
Invalid Invalid Valid Valid
Valid Valid Invalid Invalid
Invalid Valid Invalid Valid
Invalid Valid Valid Invalid
Invalid Valid Valid Valid
+ +## Examples + +{{}} +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "oneOf": [ + { "required": [ "foo" ] }, + { "required": [ "bar" ] }, + { "required": [ "baz" ] } + ] +} +{{}} + +{{}} +{ "foo": 1 } +{{}} + +{{}} +{ "bar": 2 } +{{}} + +{{}} +{ "foo": 1, "bar": 2 } +{{}} + +{{}} +{ "foo": 1, "bar": 2, "baz": 3 } +{{}} + +{{}} +{ "extra": 4 } +{{}} diff --git a/content/draft4/validation/pattern.markdown b/content/draft4/validation/pattern.markdown index 7696bcd0..54f1a023 100644 --- a/content/draft4/validation/pattern.markdown +++ b/content/draft4/validation/pattern.markdown @@ -21,3 +21,55 @@ related: - vocabulary: validation keyword: patternProperties --- + + +The [`pattern`]({{< ref "draft4/validation/pattern" >}}) keyword restricts +string instances to match the given regular expression. + +{{}} While the specification suggests the use of +[ECMA-262](https://www.ecma-international.org/publications-and-standards/standards/ecma-262/) +regular expressions for interoperability purposes, the use of different +flavours like PCRE or POSIX (Basic or Extended) is permitted. Also, the +specification does not impose the use of any particular regular expression +flag. By convention (and somewhat enforced by the official JSON Schema test +suite), regular expressions are not implicitly +[anchored](https://www.regular-expressions.info/anchors.html) and are always +treated as case-sensitive. It is also common for the +[`DOTALL`](https://tc39.es/ecma262/multipage/text-processing.html#sec-get-regexp.prototype.dotAll) +flag to be enabled, permitting the dot character class to match new lines. + +To avoid interoperability issues, stick to +[ECMA-262](https://www.ecma-international.org/publications-and-standards/standards/ecma-262/), +and don't assume the use of any regular expression flag. {{}} + +{{}} Regular expressions often make use of characters that need +to be escaped when making use of them as part of JSON strings. For example, the +*reverse solidus* character (more commonly known as the backslash character) +and the *double quote* character need to be escaped. Failure to do so will +result in an invalid JSON document. Applications to work with regular +expressions, like [Regex Forge](https://regexforge.com), typically provide +convenient functionality to copy a regular expression for use in JSON. +{{}} + +{{}} + +## Examples + +{{}} +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "pattern": "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$" +} +{{}} + +{{}} +"john.doe@example.com" +{{}} + +{{}} +"foo" +{{}} + +{{}} +1234 +{{}} diff --git a/content/draft4/validation/patternProperties.markdown b/content/draft4/validation/patternProperties.markdown index 7303596e..5a1c8ae4 100644 --- a/content/draft4/validation/patternProperties.markdown +++ b/content/draft4/validation/patternProperties.markdown @@ -28,3 +28,136 @@ related: - vocabulary: validation keyword: maxProperties --- + + +The [`patternProperties`]({{< ref "draft4/validation/patternproperties" >}}) +keyword restricts properties of an object instance that match certain regular +expressions to match their corresponding subschemas definitions. + +{{}} This keyword is evaluated independently of the +[`properties`]({{< ref "draft4/validation/properties" >}}) keyword. If an +object property is described by both keywords, then both subschemas must +successfully validate against the given property for validation to succeed. +Furthermore, an instance property may match more than one regular expression +set with this keyword, in which case the property is expected to validate +against all matching subschemas.{{}} + +{{}} While the specification suggests the use of +[ECMA-262](https://www.ecma-international.org/publications-and-standards/standards/ecma-262/) +regular expressions for interoperability purposes, the use of different +flavours like PCRE or POSIX (Basic or Extended) is permitted. Also, the +specification does not impose the use of any particular regular expression +flag. By convention (and somewhat enforced by the official JSON Schema test +suite), regular expressions are not implicitly +[anchored](https://www.regular-expressions.info/anchors.html) and are always +treated as case-sensitive. It is also common for the +[`DOTALL`](https://tc39.es/ecma262/multipage/text-processing.html#sec-get-regexp.prototype.dotAll) +flag to be enabled, permitting the dot character class to match new lines. + +To avoid interoperability issues, stick to +[ECMA-262](https://www.ecma-international.org/publications-and-standards/standards/ecma-262/), +and don't assume the use of any regular expression flag. {{}} + +{{}} Regular expressions often make use of characters that need +to be escaped when making use of them as part of JSON strings. For example, the +*reverse solidus* character (more commonly known as the backslash character) +and the *double quote* character need to be escaped. Failure to do so will +result in an invalid JSON document. Applications to work with regular +expressions, like [Regex Forge](https://regexforge.com), typically provide +convenient functionality to copy a regular expression for use in JSON. +{{}} + +{{}} + +## Examples + +{{}} +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "patternProperties": { + "^[a-z]+$": { "type": "integer" } + } +} +{{}} + +{{}} +{ "foo": 1, "bar": 2, "baz": 3 } +{{}} + +{{}} +{ "CamelCase": true, "alphanumeric123": "anything is valid" } +{{}} + +{{}} +{} +{{}} + +{{}} +{ "foo": "should have been an integer" } +{{}} + +{{}} +"Hello World" +{{}} + +{{}} +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "patternProperties": { + "^f": { "type": "string" }, + "o$": { "minLength": 3 } + } +} +{{}} + +{{}} +{ "foo": "long string" } +{{}} + +{{}} +{ "boo": 1 } +{{}} + +{{}} +{ "foo": "xx" } +{{}} + +{{}} +{ "boo": "xx" } +{{}} + +{{}} +"Hello World" +{{}} + +{{}} +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "patternProperties": { + "^f": { "minLength": 3 } + }, + "properties": { + "foo": { "type": "string" } + } +} +{{}} + +{{}} +{ "foo": "long string" } +{{}} + +{{}} +{ "football": 3 } +{{}} + +{{}} +{ "foo": "xx" } +{{}} + +{{}} +{} +{{}} + +{{}} +"Hello World" +{{}} diff --git a/content/draft4/validation/properties.markdown b/content/draft4/validation/properties.markdown index d5161408..c81b1184 100644 --- a/content/draft4/validation/properties.markdown +++ b/content/draft4/validation/properties.markdown @@ -28,3 +28,100 @@ related: - vocabulary: validation keyword: maxProperties --- + + +The [`properties`]({{< ref "draft4/validation/properties" >}}) keyword +restricts properties of an object instance, when present, to match their +corresponding subschemas definitions. + +{{}}The use of this keyword **does not prevent the presence of +other properties** in the object instance and **does not enforce the presence +of the declared properties**. In other words, additional data that is not +explicitly prohibited is permitted by default. This is intended behaviour to +ease schema evolution (open schemas are backwards compatible by default) and to +enable highly-expressive constraint-driven schemas. + +If you want to restrict instances to only contain the properties you declared, +you must set the [`additionalProperties`]({{< ref "draft4/validation/additionalproperties" >}}) keyword to the boolean schema +`false`, and if you want to enforce the presence of certain properties, you +must use the [`required`]({{< ref "draft4/validation/required" >}}) keyword +accordingly. {{}} + +{{}}Setting properties defined by this keyword to the boolean +schema `false` is an common trick to express that such properties are +forbidden. This is considered more elegant (and usually more performant) than +using the [`not`]({{< ref "draft4/validation/not" >}}) applicator to negate +the [`required`]({{< ref "draft4/validation/required" >}}) keyword. However, +setting properties defined by this keyword to the boolean `true` is considered +to be redundant and an anti-pattern, as additional properties are permitted by +default. {{}} + +{{}} This keyword is evaluated independently of the +[`patternProperties`]({{< ref "draft4/validation/patternproperties" >}}) +keyword. If an object property is described by both keywords, then both schemas +must successfully validate against the given property for validation to +succeed. {{}} + +{{}} + +## Examples + +{{}} +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "properties": { + "name": { "type": "string" }, + "age": { "type": "integer" } + } +} +{{}} + +{{}} +{ "name": "John Doe", "age": 50 } +{{}} + +{{}} +{ "name": "John Doe" } +{{}} + +{{}} +{} +{{}} + +{{}} +{ "name": "John Doe", "age": "this should have been an integer" } +{{}} + +{{}} +{ "name": 999 } +{{}} + +{{}} +"Hello World" +{{}} + +{{}} +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "properties": { + "forbidden": false, + "permitted": true + } +} +{{}} + +{{}} +{ "permitted": "anything is valid" } +{{}} + +{{}} +{ "foo": "bar", "baz": 2 } +{{}} + +{{}} +{ "forbidden": 1 } +{{}} + +{{}} +{ "forbidden": 1, "permitted": 2 } +{{}} diff --git a/content/draft4/validation/required.markdown b/content/draft4/validation/required.markdown index 8136649c..e0d97fe1 100644 --- a/content/draft4/validation/required.markdown +++ b/content/draft4/validation/required.markdown @@ -21,3 +21,80 @@ related: - vocabulary: validation keyword: minProperties --- + + +The [`required`]({{< ref "draft4/validation/required" >}}) keyword restricts +object instances to define the given set of properties. + +{{}} The presence of this keyword does not depend on the +presence of the [`properties`]({{< ref "draft4/validation/properties" >}}) +keyword. The [`required`]({{< ref "draft4/validation/required" >}}) keyword +mandates that certain properties are present (independently of their value), +while the [`properties`]({{< ref "draft4/validation/properties" >}}) keyword +describes the value of such properties when present.{{}} + +{{}} + +## Examples + +{{}} +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "required": [ "foo", "bar", "baz" ] +} +{{}} + +{{}} +{ "foo": 1, "bar": 2, "baz": 3 } +{{}} + +{{}} +{ "foo": 1, "bar": 2, "baz": 3, "extra": true } +{{}} + +{{}} +{ "foo": 1, "bar": 2, "extra": true } +{{}} + +{{}} +{} +{{}} + +{{}} +"Hello World" +{{}} + +{{}} +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "required": [ "name", "age" ], + "properties": { + "name": { "type": "string" }, + "age": { "type": "integer" } + } +} +{{}} + +{{}} +{ "name": "John Doe", "age": 30 } +{{}} + +{{}} +{ "name": "John Doe", "age": 30, "extra": true } +{{}} + +{{}} +{ "name": "John Doe" } +{{}} + +{{}} +{ "name": 123, "age": "foo" } +{{}} + +{{}} +{} +{{}} + +{{}} +"Hello World" +{{}} diff --git a/content/draft4/validation/title.markdown b/content/draft4/validation/title.markdown index 6876f79a..ff7c0dd3 100644 --- a/content/draft4/validation/title.markdown +++ b/content/draft4/validation/title.markdown @@ -15,3 +15,76 @@ related: - vocabulary: validation keyword: default --- + + +The [`title`]({{< ref "draft4/validation/title" >}}) keyword is a placeholder +for a concise human-readable string summary of what a schema or any of its +subschemas are about. This keyword is merely descriptive and does not affect +validation. + +{{}} + +We heavily recommend to declare this keyword at the top level of every schema, +as a human-readable introduction to what the schema is about. + +When doing so, note that the JSON Schema specification does not impose or +recommend a maximum length for this keyword. However, it is common practice to +stick to [Git commit message +title](https://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html) +conventions and set it to a capitalised string of *50 characters or less*. If +you run out of space, you can move the additional information to the +[`description`]({{< ref "draft4/validation/description" >}}) keyword. + +{{}} + + +## Examples + +{{}} +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "title": "Even Number", + "type": "number", + "multipleOf": 2 +} +{{}} + +{{}} +10 +{{}} + +{{}} +7 +{{}} + +{{}} +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "title": "Number", + "type": "number", + "anyOf": [ + { + "title": "Even Number", + "multipleOf": 2 + }, + { + "title": "Odd Number", + "not": { + "multipleOf": 2 + } + } + ] +} +{{}} + +{{}} +10 +{{}} + +{{}} +7 +{{}} + +{{}} +"Hello World" +{{}} diff --git a/content/draft4/validation/type.markdown b/content/draft4/validation/type.markdown index 1784ce56..6a47b4a3 100644 --- a/content/draft4/validation/type.markdown +++ b/content/draft4/validation/type.markdown @@ -14,3 +14,124 @@ tests: index: -99999 introduced_in: draft1 --- + + +The supported types are the following. Note that while the [ECMA +404](https://ecma-international.org/publications-and-standards/standards/ecma-404/) +JSON standard defines the JSON grammar without mention of encodings, the [IETF +RFC 8259](https://www.rfc-editor.org/rfc/rfc8259) JSON standard provides +specific guidance for JSON numbers and JSON strings which are documented in the +*Interoperable Encoding* column. Other encodings will likely not be accepted by +JSON parsers. + +| Type | Description | Interoperable Encoding | +|-------------|------------------------------------------|----------------------------------------------------------------------------------------------------------| +| `"null"` | The JSON null constant | N/A | +| `"boolean"` | The JSON true or false constants | N/A | +| `"object"` | A JSON object | N/A | +| `"array"` | A JSON array | N/A | +| `"number"` | A JSON number | [IEEE 764](https://ieeexplore.ieee.org/document/8766229) 64-bit double-precision floating point encoding (except `NaN`, `Infinity`, and `+0`) | +| `"integer"` | A JSON number _without a fractional component_ | 64-bit signed integer encoding (from `-(2^53)+1` to `(2^53)-1`) | +| `"string"` | A JSON string | [UTF-8](https://en.wikipedia.org/wiki/UTF-8) Unicode encoding | + +{{}} The `integer` logical type does not consider real numbers +with a zero fractional component as integers. For example, `2` is considered to +be an integer, but `2.0` is not.{{}} + +Note that while the JSON grammar does not distinguish between integer and real +numbers, JSON Schema provides the `integer` logical type that matches numbers +without a fractional component. Additionally, numeric constructs inherent to +floating point encodings (like `NaN` and `Infinity`) are not permitted in JSON. +However, the negative zero (`-0`) is permitted. + +{{}} To avoid interoperability issues, do not produce JSON +documents with numbers that exceed the [IETF RFC +8259](https://www.rfc-editor.org/rfc/rfc8259) limits described in the +*Interoperable Encodings* column of the table above. + +If more numeric precision is required, consider representing numbers as JSON +strings or as multiple numbers. For example, fixed-precision real numbers can +be represented as an array of two integers for the integral and fractional +components.{{}} + +{{}} The JavaScript programming language (and by extension +languages such as TypeScript) represent all numbers, including integers, using +the [IEEE 764](https://ieeexplore.ieee.org/document/8766229) floating-point +encoding. As a result, parsing JSON documents with integers beyond the 53-bit +range is prone to precision problems. Read [How numbers are encoded in +JavaScript](https://2ality.com/2012/04/number-encoding.html) by Dr. Axel +Rauschmayer for a more detailed overview of JavaScript's numeric +limitations.{{}} + +{{}}JSON allows numbers to be represented in [scientific +exponential +notation](https://en.wikipedia.org/wiki/Scientific_notation#E_notation). For +example, numbers like `1.0e+28` (equivalent to 10000000000000000000000000000.0) +are valid according to the JSON grammar. This notation is convenient for +expressing long numbers. However, be careful with not accidentally exceeding +the interoperable limits described by the [IETF RFC +8259](https://www.rfc-editor.org/rfc/rfc8259) JSON +standard.{{}} + +## Examples + +{{< schema "A schema that describes numeric instances" >}} +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "type": "number" +} +{{< /schema >}} + +{{< instance-pass "An integer is valid" >}} +42 +{{< /instance-pass >}} + +{{< instance-pass "A real number is valid" >}} +3.14 +{{< /instance-pass >}} + +{{< instance-pass "A number in scientific exponential notation is valid" >}} +1.0e+28 +{{< /instance-pass >}} + +{{< instance-fail "A string is not valid" >}} +"foo" +{{< /instance-fail >}} + +{{< schema "A schema that describes boolean or array instances" >}} +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "type": [ "boolean", "array" ] +} +{{< /schema >}} + +{{< instance-pass "The true boolean is valid" >}} +true +{{< /instance-pass >}} + +{{< instance-fail "A number is invalid" >}} +1234 +{{< /instance-fail >}} + +{{< instance-pass "An arbitrary array is valid" >}} +[ 1, 2, 3 ] +{{< /instance-pass >}} + +{{< schema "A schema that describes integer instances" >}} +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "type": "integer" +} +{{< /schema >}} + +{{< instance-pass "An integer is valid" >}} +42 +{{< /instance-pass >}} + +{{< instance-fail "A real number with a zero fractional component is invalid" >}} +3.0 +{{< /instance-fail >}} + +{{< instance-fail "A real number with a non-zero fractional component is invalid" >}} +3.14 +{{< /instance-fail >}} diff --git a/content/draft4/validation/uniqueItems.markdown b/content/draft4/validation/uniqueItems.markdown index d048aa6d..aa0d291a 100644 --- a/content/draft4/validation/uniqueItems.markdown +++ b/content/draft4/validation/uniqueItems.markdown @@ -19,3 +19,65 @@ related: - vocabulary: validation keyword: additionalItems --- + + +When set to `true`, the [`uniqueItems`]({{< ref "draft4/validation/uniqueitems" >}}) keyword restricts array instances to +items that only occur once in the array. Note that empty arrays and arrays that +consist of a single item satisfy uniqueness by definition. + +{{}} Keep in mind that depending on the size and complexity of +arrays, this keyword may introduce significant validation overhead. The paper +[JSON: data model, query languages and schema +specification](https://arxiv.org/abs/1701.02221) also noted how the presence of +this keyword can negatively impact satisfiability analysis of +schemas.{{}} + +{{}} + +## Examples + +{{}} +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "uniqueItems": true +} +{{}} + +{{}} +[ 1, "hello", true, { "name": "John" } ] +{{}} + +{{}} +[ { "name": "John" }, 1, "hello", true, { "name": "John" } ] +{{}} + +{{}} +[] +{{}} + +{{}} +"Hello World" +{{}} + +{{}} +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "uniqueItems": false +} +{{}} + +{{}} +[ 1, "hello", true, { "name": "John" } ] +{{}} + +{{}} +[ { "name": "John" }, 1, "hello", true, { "name": "John" } ] +{{}} + +{{}} +[] +{{}} + +{{}} +"Hello World" +{{}} diff --git a/content/draft6/validation/description.markdown b/content/draft6/validation/description.markdown index ca842052..1a2d3860 100644 --- a/content/draft6/validation/description.markdown +++ b/content/draft6/validation/description.markdown @@ -67,7 +67,7 @@ cases. {{}} { - "$schema": "http://json-schema.org/draft-07/schema#", + "$schema": "http://json-schema.org/draft-06/schema#", "title": "Number", "type": "number", "anyOf": [ diff --git a/content/draft6/validation/title.markdown b/content/draft6/validation/title.markdown index 0fca191f..8c709860 100644 --- a/content/draft6/validation/title.markdown +++ b/content/draft6/validation/title.markdown @@ -61,18 +61,18 @@ you run out of space, you can move the additional information to the {{}} { - "$schema": "http://json-schema.org/draft-07/schema#", + "$schema": "http://json-schema.org/draft-06/schema#", "title": "Number", "type": "number", "anyOf": [ - { + { "title": "Even Number", - "multipleOf": 2 + "multipleOf": 2 }, - { + { "title": "Odd Number", "not": { - "multipleOf": 2 + "multipleOf": 2 } } ] diff --git a/content/draft6/validation/type.markdown b/content/draft6/validation/type.markdown index b2fd4a49..d2e8db8d 100644 --- a/content/draft6/validation/type.markdown +++ b/content/draft6/validation/type.markdown @@ -37,11 +37,11 @@ JSON parsers. | `"string"` | A JSON string | [UTF-8](https://en.wikipedia.org/wiki/UTF-8) Unicode encoding | Note that while the JSON grammar does not distinguish between integer and real -numbers, JSON Schema provides the [`integer`]({{< ref "draft6/validation/type" >}}) logical type that matches either integers (such -as `2`), or real numbers where the fractional part is zero (such as `2.0`). -Additionally, numeric constructs inherent to floating point encodings (like -`NaN` and `Infinity`) are not permitted in JSON. However, the negative zero -(`-0`) is permitted. +numbers, JSON Schema provides the `integer` logical type that matches either +integers (such as `2`), or real numbers where the fractional part is zero (such +as `2.0`). Additionally, numeric constructs inherent to floating point +encodings (like `NaN` and `Infinity`) are not permitted in JSON. However, the +negative zero (`-0`) is permitted. {{}} To avoid interoperability issues, do not produce JSON documents with numbers that exceed the [IETF RFC diff --git a/content/draft7/validation/type.markdown b/content/draft7/validation/type.markdown index 60a2d63d..19a29522 100644 --- a/content/draft7/validation/type.markdown +++ b/content/draft7/validation/type.markdown @@ -37,11 +37,11 @@ JSON parsers. | `"string"` | A JSON string | [UTF-8](https://en.wikipedia.org/wiki/UTF-8) Unicode encoding | Note that while the JSON grammar does not distinguish between integer and real -numbers, JSON Schema provides the [`integer`]({{< ref "draft7/validation/type" >}}) logical type that matches either integers (such -as `2`), or real numbers where the fractional part is zero (such as `2.0`). -Additionally, numeric constructs inherent to floating point encodings (like -`NaN` and `Infinity`) are not permitted in JSON. However, the negative zero -(`-0`) is permitted. +numbers, JSON Schema provides the `integer` logical type that matches either +integers (such as `2`), or real numbers where the fractional part is zero (such +as `2.0`). Additionally, numeric constructs inherent to floating point +encodings (like `NaN` and `Infinity`) are not permitted in JSON. However, the +negative zero (`-0`) is permitted. {{}} To avoid interoperability issues, do not produce JSON documents with numbers that exceed the [IETF RFC