forked from json-schema-org/json-schema-org.github.io
-
Notifications
You must be signed in to change notification settings - Fork 0
/
example1.html
275 lines (247 loc) · 8.43 KB
/
example1.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
---
layout: page
---
<h2>Example data</h2>
<div class="block">
<p>Let's pretend we're interacting with a JSON based product catalog. This catalog has a product which has an <em>id</em>, a <em>name</em>, a <em>price</em>, and an optional set of <em>tags</em>.</p>
<h3>Example JSON data for a product API</h3>
<p>An example product in this API is:</p>
<pre class="json">
{
"id": 1,
"name": "A green door",
"price": 12.50,
"tags": ["home", "green"]
}
</pre>
<p>While generally straightforward, that example leaves some open questions. For example, one may ask:</p>
<ul>
<li>What is id?</li>
<li>Is name required?</li>
<li>Can price be 0?</li>
<li>Are all tags strings?</li>
</ul>
<p>When you're talking about a data format, you want to have metadata about what fields mean, and what valid inputs for those fields are. JSON schema is a specification for standardizing how to answer those questions for JSON data.</p>
</div>
<h2>Starting the schema</h2>
<div class="block">
<p>To start a schema definition, let's begin with a basic JSON schema:</p>
<pre class="json-schema">
{
"$schema": "http://json-schema.org/draft-04/schema#",
"title": "Product",
"description": "A product from Acme's catalog",
"type": "object"
}
</pre>
<p>The above schema has four properties called <em>keywords</em>.
The <em>title</em> and <em>description</em> keywords are descriptive only, in that they do not add
constraints to the data being validated. The intent of the schema is stated with these two keywords
(that is, this schema describes a product).</p>
<p>The <em>type</em> keyword defines the first constraint on our JSON data: it has to be a JSON
Object.</p>
<p>Finally, the <em>$schema</em> keyword states that this schema is written according to the draft
v4 specification.</p>
</div>
<h2>Defining the properties</h2>
<div class="block">
<p>Next let's answer our previous questions about this API, starting with id.</p>
<h3>What is id?</h3>
<p><em>id</em> is a numeric value that uniquely identifies a product. Since this is the canonical identifier for a product, it doesn't make sense to have a product without one, so it is required.</p>
<p>In JSON Schema terms, we can update our schema to:</p>
<pre class="json-schema">
{
"$schema": "http://json-schema.org/draft-04/schema#",
"title": "Product",
"description": "A product from Acme's catalog",
"type": "object",
"properties": {
"id": {
"description": "The unique identifier for a product",
"type": "integer"
}
},
"required": ["id"]
}
</pre>
<h3>Is name required?</h3>
<p><em>name</em> is a string value that describes a product. Since there isn't
much to a product without a name, it also is required. Adding this gives us the schema:</p>
<pre class="json-schema">
{
"$schema": "http://json-schema.org/draft-04/schema#",
"title": "Product",
"description": "A product from Acme's catalog",
"type": "object",
"properties": {
"id": {
"description": "The unique identifier for a product",
"type": "integer"
},
"name": {
"description": "Name of the product",
"type": "string"
}
},
"required": ["id", "name"]
}
</pre>
<h3>Can price be 0?</h3>
<p>According to Acme's docs, there are no free products. In JSON schema a number can have a minimum. By default this minimum is inclusive, so we need to specify <em>exclusiveMinimum</em>. Therefore we can update our schema with <em>price</em>:</p>
<pre class="json-schema">
{
"$schema": "http://json-schema.org/draft-04/schema#",
"title": "Product",
"description": "A product from Acme's catalog",
"type": "object",
"properties": {
"id": {
"description": "The unique identifier for a product",
"type": "integer"
},
"name": {
"description": "Name of the product",
"type": "string"
},
"price": {
"type": "number",
"minimum": 0,
"exclusiveMinimum": true
}
},
"required": ["id", "name", "price"]
}
</pre>
<h3>Are all tags strings?</h3>
<p>Finally, we come to the <em>tags</em> property. Unlike the previous
properties, tags have many values, and is represented as a JSON array. According
to Acme's docs, all tags must be strings, but you aren't required to specify
tags. We simply leave <em>tags</em> out of the list of required properties.</p>
<p>However, Acme's docs add two constraints:</p>
<ul>
<li>there must be at least one tag,</li>
<li>all tags must be unique.</li>
</ul>
<p>The first constraint can be added with <em>minItems</em>, and the second one by
specifying <em>uniqueItems</em> as being true:</p>
<pre class="json-schema">
{
"$schema": "http://json-schema.org/draft-04/schema#",
"title": "Product",
"description": "A product from Acme's catalog",
"type": "object",
"properties": {
"id": {
"description": "The unique identifier for a product",
"type": "integer"
},
"name": {
"description": "Name of the product",
"type": "string"
},
"price": {
"type": "number",
"minimum": 0,
"exclusiveMinimum": true
},
"tags": {
"type": "array",
"items": {
"type": "string"
},
"minItems": 1,
"uniqueItems": true
}
},
"required": ["id", "name", "price"]
}
</pre>
</div>
<h2>Summary</h2>
<div class="block">
<p>The above example is by no means definitive of all the types of data JSON schema can define. For more definitive information see the <a href="#definitions">full standard draft</a>.</p>
<p>As a final example, here's a spec for an array of products, with the products having 2 new properties. The first is a <em>dimensions</em> property for the size of the product, and the second is a <em>warehouseLocation</em> field for where the warehouse that stores them is geographically located.</p>
<p>And also, since JSON Schema defines a reference schema for a geographic location, instead of coming up with our own, we'll reference the <a href="http://json-schema.org/geo">canonical one</a>.</p>
<h3>Set of products:</h3>
<pre class="json">
[
{
"id": 2,
"name": "An ice sculpture",
"price": 12.50,
"tags": ["cold", "ice"],
"dimensions": {
"length": 7.0,
"width": 12.0,
"height": 9.5
},
"warehouseLocation": {
"latitude": -78.75,
"longitude": 20.4
}
},
{
"id": 3,
"name": "A blue mouse",
"price": 25.50,
"dimensions": {
"length": 3.1,
"width": 1.0,
"height": 1.0
},
"warehouseLocation": {
"latitude": 54.4,
"longitude": -32.7
}
}
]
</pre>
<h3>Set of products schema:</h3>
<pre class="json-schema">
{
"$schema": "http://json-schema.org/draft-04/schema#",
"title": "Product set",
"type": "array",
"items": {
"title": "Product",
"type": "object",
"properties": {
"id": {
"description": "The unique identifier for a product",
"type": "number"
},
"name": {
"type": "string"
},
"price": {
"type": "number",
"minimum": 0,
"exclusiveMinimum": true
},
"tags": {
"type": "array",
"items": {
"type": "string"
},
"minItems": 1,
"uniqueItems": true
},
"dimensions": {
"type": "object",
"properties": {
"length": {"type": "number"},
"width": {"type": "number"},
"height": {"type": "number"}
},
"required": ["length", "width", "height"]
},
"warehouseLocation": {
"description": "Coordinates of the warehouse with the product",
"$ref": "http://json-schema.org/geo"
}
},
"required": ["id", "name", "price"]
}
}
</pre>
</div>