|
| 1 | +.. index:: |
| 2 | + single: $schema |
| 3 | + |
| 4 | +Declaring a Specification Version |
| 5 | +================================= |
| 6 | + |
| 7 | +.. contents:: :local: |
| 8 | + |
| 9 | +Not only have there have been multiple versions of the specification, |
| 10 | +but it's also possible to add your own extensions to create your own |
| 11 | +version. JSON Schema provides ways for you to declare which version |
| 12 | +a schema conforms to and provides ways to describe your custom |
| 13 | +keywords. |
| 14 | + |
1 | 15 | .. index::
|
2 | 16 | single: $schema
|
3 | 17 | single: schema; keyword
|
4 | 18 |
|
5 | 19 | .. _schema:
|
6 | 20 |
|
7 |
| -The $schema keyword |
8 |
| -=================== |
| 21 | +$schema |
| 22 | +------- |
9 | 23 |
|
10 |
| -.. contents:: :local: |
| 24 | +The ``$schema`` keyword is used to declare which version of the JSON |
| 25 | +Schema specification the schema was written for. The value of the |
| 26 | +``$schema`` keyword is also the identifier for a schema that can be |
| 27 | +used to verify that the schema is valid according to the specification |
| 28 | +version ``$schema`` identifies. A schema that describes another schema |
| 29 | +is called a "meta-schema". |
| 30 | + |
| 31 | +``$schema`` applies to the entire document and must be at the root |
| 32 | +level. It does not apply to externally referenced (``$ref``) |
| 33 | +documents. Those schemas need to declare their own ``$schema``. |
| 34 | + |
| 35 | +If ``$schema`` is not used, an implementation might allow you to |
| 36 | +specify a value externally or it might make assumptions about which |
| 37 | +specification version should be used to evaluate the schema. It's |
| 38 | +recommended that all JSON Schemas have a ``$schema`` entry to |
| 39 | +communicate to readers and tooling which specification version is |
| 40 | +intended. Therefore most of the time, you'll want this at the root of |
| 41 | +your schema:: |
| 42 | + |
| 43 | + "$schema": "http://json-schema.org/draft-07/schema#" |
| 44 | + |
| 45 | +.. draft_specific:: |
| 46 | + |
| 47 | + --Draft-4 |
| 48 | + The identifier for Draft 4 is ``http://json-schema.org/draft-04/schema#``. |
| 49 | + |
| 50 | + Draft 4 defined a value for ``$schema`` without a specific version |
| 51 | + (``http://json-schema.org/schema#``) which meant, use the latest |
| 52 | + version. This has since been deprecated and should no longer be |
| 53 | + used. |
| 54 | + |
| 55 | + You might come across references to Draft 5. There is no Draft 5 |
| 56 | + release of JSON Schema. Draft 5 refers to a no-change revision of |
| 57 | + the Draft 4 release. It does not add, remove, or change any |
| 58 | + functionality. It only updates references, makes clarifications, |
| 59 | + and fixes bugs. Draft 5 describes the Draft 4 release. If you came |
| 60 | + here looking for information about Draft 5, you'll find it under |
| 61 | + Draft 4. We no longer use the "draft" terminology to refer to |
| 62 | + patch releases to avoid this confusion. |
| 63 | + |
| 64 | + --Draft-6 |
| 65 | + The identifier for Draft 6 is ``http://json-schema.org/draft-06/schema#``. |
| 66 | + |
| 67 | +.. index:: |
| 68 | + single: $schema |
| 69 | + single: schema; custom |
| 70 | + single: schema; extending |
| 71 | + |
| 72 | +Extending JSON Schema |
| 73 | +--------------------- |
| 74 | + |
| 75 | +You can extended the JSON Schema language to include your own custom |
| 76 | +keywords. To do this, you need to create a meta-schema that includes |
| 77 | +your custom keywords. The best way to do this is to make a copy of the |
| 78 | +meta-schema for the version you want to extend and make your changes |
| 79 | +to your copy. You will need to choose a custom URI to identify your |
| 80 | +custom version. This URI must not be one of the URIs used to identify |
| 81 | +official JSON Schema specification drafts and should probably include |
| 82 | +a domain name you own. You can use this URI with the ``$schema`` |
| 83 | +keyword to declare that your schemas use your custom version. |
| 84 | + |
| 85 | +.. note:: |
| 86 | + Not all implementations support extending JSON Schema. |
| 87 | + |
| 88 | +One of the strengths of JSON Schema is that it can be written in JSON |
| 89 | +and used in a variety of environments. For example, it can be used for |
| 90 | +both front-end and back-end HTML Form validation. The problem with |
| 91 | +adding custom keywords is that every environment where you want to use |
| 92 | +your schemas needs to understand how to evaluate your custom keywords. |
| 93 | +Meta-schemas can be used to ensure that schemas are written correctly, |
| 94 | +but each implementation will need custom code to understand how to |
| 95 | +evaluate the custom keywords. |
| 96 | + |
| 97 | +Meta-data keywords are the most interoperable because they don't |
| 98 | +affect validation. For example, you could add a ``units`` keyword. |
| 99 | +This will always work as expecting with an compliant validator. |
11 | 100 |
|
12 |
| -The ``$schema`` keyword is used to declare that a JSON fragment is |
13 |
| -actually a piece of JSON Schema. It also declares which version of |
14 |
| -the JSON Schema standard that the schema was written against. |
| 101 | +.. schema_example:: |
15 | 102 |
|
16 |
| -It is recommended that all JSON Schemas have a ``$schema`` entry, |
17 |
| -which must be at the root. Therefore most of the time, you'll want |
18 |
| -this at the root of your schema:: |
| 103 | + { |
| 104 | + "type": "number", |
| 105 | + "units": "kg" |
| 106 | + } |
| 107 | + -- |
| 108 | + 42 |
| 109 | + --X |
| 110 | + "42" |
19 | 111 |
|
20 |
| - "$schema": "http://json-schema.org/draft/2019-09/schema#" |
| 112 | +The next best candidates for custom keywords are keywords that don't |
| 113 | +apply other schemas and don't modify the behavior of existing |
| 114 | +keywords. An ``isEven`` keyword is an example. In contexts where some |
| 115 | +validation is better than no validation such as validating an HTML |
| 116 | +Form in the browser, this schema will perform as well as can be |
| 117 | +expected. Full validation would still be required and should use a |
| 118 | +validator that understands the custom keyword. |
21 | 119 |
|
22 |
| -Advanced |
23 |
| --------- |
| 120 | +.. schema_example:: |
24 | 121 |
|
25 |
| -You should declare that your schema was written against a specific version |
26 |
| -of the JSON Schema standard and include the draft name in the path, for |
27 |
| -example: |
| 122 | + { |
| 123 | + "type": "integer", |
| 124 | + "isEven": true |
| 125 | + } |
| 126 | + -- |
| 127 | + 2 |
| 128 | + -- |
| 129 | + // This passes because the validator doesn't understand ``isEven`` |
| 130 | + 3 |
| 131 | + --X |
| 132 | + // The schema isn't completely impaired because it doesn't understand ``isEven`` |
| 133 | + "3" |
28 | 134 |
|
29 |
| -- ``http://json-schema.org/draft/2019-09/schema#`` |
30 |
| -- ``http://json-schema.org/draft-07/schema#`` |
31 |
| -- ``http://json-schema.org/draft-06/schema#`` |
32 |
| -- ``http://json-schema.org/draft-04/schema#`` |
| 135 | +The least interoperable type of custom keyword is one that applies |
| 136 | +other schemas or modifies the behavior of existing keywords. An |
| 137 | +example would be something like ``requiredProperties`` that declares |
| 138 | +properties and makes them required. This example shows how the schema |
| 139 | +becomes almost completely useless when evaluated with a validator that |
| 140 | +doesn't understand the custom keyword. That doesn't necessarily mean |
| 141 | +that ``requiredProperties`` is a bad idea for a keyword, it's just not |
| 142 | +the right choice if the schema might need to be used in a context that |
| 143 | +doesn't understand custom keywords. |
33 | 144 |
|
34 |
| -The possibility to declare ``$schema`` without specific version (``http://json-schema.org/schema#``) was deprecated after Draft 4 and should no longer be used. |
| 145 | +.. schema_example:: |
35 | 146 |
|
36 |
| -Additionally, if you have extended the JSON Schema language to include |
37 |
| -your own custom keywords for validating values, you can use a custom |
38 |
| -URI for ``$schema``. It must not be one of the predefined values |
39 |
| -above, and should probably include a domain name you own. |
| 147 | + { |
| 148 | + "type": "object", |
| 149 | + "requiredProperties": { |
| 150 | + "foo": { "type": "string" } |
| 151 | + } |
| 152 | + } |
| 153 | + -- |
| 154 | + { "foo": "bar" } |
| 155 | + -- |
| 156 | + // This passes because ``requiredProperties`` is not understood |
| 157 | + {} |
| 158 | + -- |
| 159 | + // This passes because ``requiredProperties`` is not understood |
| 160 | + { "foo": 42 } |
0 commit comments