Skip to content

Add guidance on bundling and references #792

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 4 commits into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
113 changes: 113 additions & 0 deletions jsonschema-core.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3414,6 +3414,57 @@ User-Agent: product-name/5.4.1 so-cool-json-schema/1.0.2 curl/7.43.0
</t>
</section>

<section title="Manipulating schema documents and references">
<t>
Various tools have been created to rearrange schema documents
based on how and where references ("$ref") appear. This appendix discusses
which use cases and actions are compliant with this specification.
</t>
<section title="Bundling schema resources into a single document">
<t>
A set of schema resources intended for use together can be organized
with each in its own schema document, all in the same schema document,
or any granularity of document grouping in between.
</t>
<t>
Numerous tools exist to perform various sorts of reference removal.
A common case of this is producing a single file where all references
can be resolved within that file. This is typically done to simplify
distribution, or to simplify coding so that various invocations
of JSON Schema libraries do not have to keep track of and load
a large number of resources.
</t>
<t>
This transformation can be safely and reversibly done as long as
all static references (e.g. "$ref") use URI-references that resolve
to canonical URIs, and all schema resources have an absolute-URI
as the "$id" in their root schema.
</t>
<t>
With these conditions met, each external resource can be copied
under "$defs", without breaking any references among the resources'
schema objects, and without changing any aspect of validation or
annotation results. The names of the schemas under "$defs" do
not affect behavior, assuming they are each unique, as they
do not appear in canonical URIs for the embedded resources.
</t>
</section>
<section title="Reference removal is not always safe">
<t>
Attempting to remove all references and produce a single schema document does not,
in all cases, produce a schema with identical behavior to the original form.
</t>
<t>
Since "$ref" is now treated like any other keyword, with other keywords allowed
in the same schema objects, fully supporting non-recursive "$ref" removal in
all cases can require relatively complex schema manipulations. It is beyond
the scope of this specification to determine or provide a set of safe "$ref"
removal transformations, as they depend not only on the schema structure
but also on the intended usage.
</t>
</section>
</section>

<section title="Working with vocabularies">
<section title="Best practices for vocabulary and meta-schema authors">
<t>
Expand Down Expand Up @@ -3589,6 +3640,68 @@ User-Agent: product-name/5.4.1 so-cool-json-schema/1.0.2 curl/7.43.0
</section>
</section>

<section title="References and generative use cases">
<t>
While the presence of references is expected to be transparent
to validation results, generative use cases such as code generators
and UI renderers often consider references to be semantically significant.
</t>
<t>
To make such use case-specific semantics explicit, the best practice
is to create an annotation keyword for use in the same
schema object alongside of a reference keyword such as "$ref".
</t>
<figure>
<preamble>
For example, here is a hypothetical keyword for determining
whether a code generator should consider the reference
target to be a distinct class, and how those classes are related.
Note that this example is solely for illustrative purposes, and is
not intended to propose a functional code generation keyword.
</preamble>
<artwork>
<![CDATA[
{
"allOf": [
{
"classRelation": "is-a",
"$ref": "classes/base.json"
},
{
"$ref": "fields/common.json"
}
],
"properties": {
"foo": {
"classRelation": "has-a",
"$ref": "classes/foo.json"
},
"date": {
"$ref": "types/dateStruct.json",
}
}
}
]]>
</artwork>
</figure>
<t>
Here, this schema represents some sort of object-oriented class.
The first reference in the "allOf" is noted as the base class.
The second is not assigned a class relationship, meaning that the
code generator should combine the target's definition with this
one as if no reference were involved.
</t>
<t>
Looking at the properties, "foo" is flagged as object composition,
while the "date" property is not. It is simply a field with
sub-fields, rather than an instance of a distinct class.
</t>
<t>
This style of usage requires the annotation to be in the same object
as the reference, which must be recognizable as a reference.
</t>
</section>

<section title="Acknowledgments">
<t>
Thanks to
Expand Down