Skip to content
This repository was archived by the owner on Nov 2, 2023. It is now read-only.

Commit cf36567

Browse files
committed
Release Notes: Add section on embedded schemas
1 parent b0ef598 commit cf36567

File tree

1 file changed

+156
-0
lines changed

1 file changed

+156
-0
lines changed

draft/2020-12/release-notes.md

Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,162 @@ Given this schema, the instance `["a", "b", "ccc"]` will fail because `"ccc"` is
277277
considered unevaluated and fails the `unevaluatedItems` keyword like it did in
278278
previous drafts.
279279

280+
## Embedded Schemas and Bundling
281+
In Draft 2019-09, the meaning of `$id` in a sub-schema changed from indicating a
282+
base URI change within the current schema to indicating an embedded schema
283+
independent of the parent schema. A schema that contains one or more embedded
284+
schemas is called a "Compound Schema Document". This draft introduces guidance
285+
on how bundlers should embedded schemas to create Compound Schema Documents.
286+
287+
If you reference an external schema, that schema can declare it's own `$schema`
288+
and that may be different than the `$schema` of the referencing schema.
289+
Implementations need to be prepared to switch processing modes or throw an
290+
error if they don't support the `$schema` of the referenced schema. Embedded
291+
schemas work exactly the same way. They may declare a `$schema` that is not the
292+
same as the parent schema and implementations need to be prepared to handle the
293+
`$schema` change appropriately.
294+
295+
A notable consequence of embedded schemas having a different `$schema` than its
296+
parent is that implementations can't validate Compound Schema Documents directly
297+
against the meta-schema. The Compound Schema Document needs to be decomposed and
298+
each Schema Resource needs to be validated individually against the appropriate
299+
meta-schema for that schema.
300+
301+
This draft introduces official guidance on how to use embedded schemas to
302+
bundle schemas into a Compound Schema Document. The approach is designed to not
303+
have to modify schemas (other than adding to `$defs`) so that output results
304+
remain as similar as possible whether you are validating the bundled schema or
305+
following external references. Here's an example of a customer schema with
306+
external references that we want to bundle.
307+
308+
```json
309+
{
310+
"$schema": "https://json-schema.org/draft/2020-12",
311+
"$id": "https://example.com/schema/customer",
312+
313+
"type": "object",
314+
"properties": {
315+
"name": { "type": "string" },
316+
"phone": { "$ref": "/schema/common#/$defs/phone" },
317+
"address": { "$ref": "/schema/address" }
318+
}
319+
}
320+
```
321+
322+
```json
323+
{
324+
"$schema": "https://json-schema.org/draft/2020-12",
325+
"$id": "https://example.com/schema/address",
326+
327+
"type": "object",
328+
"properties": {
329+
"address": { "type": "string" },
330+
"city": { "type": "string" },
331+
"postalCode": { "type": "/schema/common#/$defs/usaPostalCode" },
332+
"state": { "type": "/$defs/states" }
333+
},
334+
335+
"$defs": {
336+
"states": {
337+
"enum": [...]
338+
}
339+
}
340+
}
341+
```
342+
343+
```json
344+
{
345+
"$schema": "https://json-schema.org/draft/2019-09",
346+
"$id": "https://example.com/schema/common",
347+
348+
"$defs": {
349+
"phone": {
350+
"type": "string",
351+
"pattern": "^[\+]?[(]?[0-9]{3}[)]?[-\s\.]?[0-9]{3}[-\s\.]?[0-9]{4,6}$"
352+
},
353+
"usaPostalCode": {
354+
"type": "string",
355+
"pattern": "^[0-9]{5}(?:-[0-9]{4})?$"
356+
},
357+
"unsignedInt": {
358+
"type": "integer",
359+
"minimum": 0
360+
}
361+
}
362+
}
363+
```
364+
365+
To bundle these schemas, we simply add each of the referenced schemas as
366+
embedded schemas using `$defs`. Here's what the bundled schema would look like.
367+
368+
```json
369+
{
370+
"$schema": "https://json-schema.org/draft/2020-12",
371+
"$id": "https://example.com/schema/customer",
372+
373+
"type": "object",
374+
"properties": {
375+
"name": { "type": "string" },
376+
"phone": { "$ref": "/schema/common#/$defs/phone" },
377+
"address": { "$ref": "/schema/address" }
378+
}
379+
380+
"$defs": {
381+
"https://example.com/schema/address": {
382+
"$id": "https://example.com/schema/address",
383+
384+
"type": "object",
385+
"properties": {
386+
"address": { "type": "string" },
387+
"city": { "type": "string" },
388+
"postalCode": { "type": "/schema/common#/$defs/usaPostalCode" },
389+
"state": { "type": "#/$defs/states" }
390+
},
391+
392+
"$defs": {
393+
"states": {
394+
"enum": [...]
395+
}
396+
}
397+
},
398+
"$id": "https://example.com/schema/common": {
399+
"$schema": "https://json-schema.org/draft/2019-09",
400+
"$id": "https://example.com/schema/common",
401+
402+
"$defs": {
403+
"phone": {
404+
"type": "string",
405+
"pattern": "^[\+]?[(]?[0-9]{3}[)]?[-\s\.]?[0-9]{3}[-\s\.]?[0-9]{4,6}$"
406+
},
407+
"usaPostalCode": {
408+
"type": "string",
409+
"pattern": "^[0-9]{5}(?:-[0-9]{4})?$"
410+
},
411+
"unsignedInt": {
412+
"type": "integer",
413+
"minimum": 0
414+
}
415+
}
416+
}
417+
}
418+
}
419+
```
420+
421+
Here are a few things you might notice from this example.
422+
423+
1. No `$ref`s were modified. Even local references are unchanged.
424+
2. `https://example.com/schema/common#/$defs/unsignedInt` got pulled in with the
425+
common schema even though it isn't used. It's allowed to trim out the extra
426+
definitions, but not necessary.
427+
3. `https://example.com/schema/address` doesn't declare a `$schema`. Because it
428+
uses the same `$schema` as `https://example.com/schema/customer`, it can skip
429+
that declaration and use the `$schema` from the schema it's embedded in.
430+
4. `https://example.com/schema/common` uses a different `$schema` than the
431+
document it's embedded in. That's allowed.
432+
5. Definitions from `https://example.com/schema/common` are used in both of the
433+
other schemas and only needs to be included once. It isn't necessary for
434+
bundlers to embed a schema inside another embedded schema.
435+
280436
## Vocabulary Changes
281437
The `unevaluatedProperties` and `unevaluatedItems` keywords have been moved from
282438
the applicator vocabulary to their own vocabulary designated which is required

0 commit comments

Comments
 (0)