Skip to content

Commit

Permalink
Control link applicability with hrefRequired
Browse files Browse the repository at this point in the history
This addresses issue json-schema-org#49.

Add a keyword, "hrefRequired", that prevents a link from being
used if a variable named in that keyword's array cannot be resolved
to a value by any available mechanism.

Remove outdated language about non-object instances causing problems,
as this is addressed by "hrefPointers".
  • Loading branch information
handrews committed Sep 13, 2017
1 parent 4d74bc8 commit 040082c
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 24 deletions.
3 changes: 3 additions & 0 deletions hyper-schema.json
Expand Up @@ -28,6 +28,9 @@
"description": "a schema for validating user input to the URI template, where the input is in the form of a JSON object with property names matching variable names in \"href\"",
"allOf": [ {"$ref": "#"} ]
},
"hrefRequired": {
"description": "an array of URI template variables names from \"href\" which must be filled out with some value, either from the instance or user input"
},
"rel": {
"description": "relation to the target resource of the link",
"type": "string"
Expand Down
73 changes: 49 additions & 24 deletions jsonschema-hyperschema.xml
Expand Up @@ -183,12 +183,6 @@
binary data treated as a PNG image.
It also defines link relations for the instance, with URIs incorporating values
from the instance.
<cref>
"id" probably should not normally be a required keyword, since new instances
will have an unknown "id" property until is it assigned by the server.
However, this property is used in a link, and without it, multiple different
instances would be given the same rel=self URI!
</cref>
</postamble>
</figure>

Expand Down Expand Up @@ -644,18 +638,23 @@

<section title="Missing values" anchor="missingValues">
<t>
Sometimes, the appropriate values will not be available.
For example, the template might specify the use of object properties,
but no such data was provided (or "hrefSchema" is not present), and the
instance is an array or a string.
Sometimes, the appropriate values will not be available. In many
cases, the URI Template behavior of simply removing varibles that
do not have a value will be appropriate. An example of this is
optional query parameters, the presence or absence of which does
not change the nature of the link relation type.
</t>

<t>
If any of the values required for the template are neither present in
the user agent data (if relevant) nor the JSON instance, then substitute
values MAY be provided from another source (such as default values).
Otherwise, the link definition SHOULD be considered not to apply to the
instance.
However, some variables, such as an identifier used in a path component,
cannot meaningfully be omitted. The resulting URI would be meaningless,
or would require a different link relation type. While "hrefSchema" can
express a requirement for those variables that can be supplied via input,
some variables must be resolved from instance data. When that instance
data is not required by the context schema, the
<xref target="hrefRequired">"hrefRequired</xref> keyword may be used to
indicate that when the instance data is not available, the link does
not apply.
</t>
</section>
</section>
Expand Down Expand Up @@ -709,7 +708,8 @@
"hrefPointers": {
"rootId": "/id",
"parentId": "2/id"
}
},
"hrefRequired": ["parentId"]
}
]
}]]>
Expand Down Expand Up @@ -761,14 +761,8 @@
</t>
<t>
For the root node, the relative pointer for the parent doesn't point
to anything. As noted under
<xref target="missingValues">missing values</xref>, such a link should
simply be ignored.
<cref>
GitHub issue #49 tracks the question of distinguishing this situation
of a missing required variable (common in path components) from
missing optional variables (common in query string parameters).
</cref>
to anything, so <xref target="hrefRequired">"hrefRequired"</xref>
prevents the link from being used with that node.
</t>
</section>

Expand Down Expand Up @@ -863,6 +857,37 @@
</t>
</section>

<section title="hrefRequired" anchor="hrefRequired">
<t>
The value of this keyword MUST be an array, and the elements MUST be unique.
Each element SHOULD match a variable in the link's URI Template, without
percent-encoding. After completing the entire URI Template resolution
process, if any variable that is present in this array does not have
a value, the link MUST NOT be used.
</t>
<figure>
<preamble>
Here is a simplified version of the "up" link from the
<xref target="hrefPointers">"hrefPointers</xref> tree example,
modified to only use the parent identifier for its "href" template.
While each individual node is required to have an "id" field, the
"up" link uses the parent node's field, and the root node, by definition,
does not have a parent node. Putting "parentId" in "hrefRequired" ensures
that the "up" link is correctly unusable with the root node.
</preamble>
<artwork>
<![CDATA[{
"rel": "up",
"href": "/nodes/{parentId}",
"hrefPointers": {
"parentId": "2/id"
},
"hrefRequired": ["parentId"]
}]]>
</artwork>
</figure>
</section>

<section title="rel" anchor="rel">
<t>
The value of the "rel" property indicates the name of the relation to the target
Expand Down
3 changes: 3 additions & 0 deletions links.json
Expand Up @@ -17,6 +17,9 @@
"description": "a schema for validating user input to the URI template, where the input is in the form of a JSON object with property names matching variable names in \"href\"",
"allOf": [ {"$ref": "#"} ]
},
"hrefRequired": {
"description": "an array of URI template variables names from \"href\" which must be filled out with some value, either from the instance or user input"
},
"rel": {
"description": "relation to the target resource of the link",
"type": "string"
Expand Down

0 comments on commit 040082c

Please sign in to comment.