Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 01c8c90

Browse files
committedDec 5, 2016
Remove "method", URI input with "hrefVars"
In the most recent draft, "method" simply controlled whether link input was placed in the URI (for a value of "get") or in the request body (for a valued of "post"). While correlating with HTML, this was both confusing due to "get" and "post" not necessarily indicating the HTTP methods of the same name, and limiting in that users/clients could not submit data through both the URI and the request body at the same time. This introduces "hrefVars" which provides schemas for user input matching the "href" URI Template variables, It removes "method" and makes "schema" and "encType" unambiguously apply to the request body in all cases. Clients should choose when to use the request body submission based on the rules of the protocol given by the URI scheme and the semantics indicated by the link relation. Additionally, the complex and apparently rarely if ever used preprocessing rules have been removed, and both the resulting and pre-existing limitations have been documented. They will be the subject of work for future drafts. The meta-schemas have been updated accordingly, and the LDO schema has been brought over from the web site repo and updated. Improper use of "$ref" has been fixed with "allOf".
1 parent fac35a0 commit 01c8c90

File tree

3 files changed

+235
-175
lines changed

3 files changed

+235
-175
lines changed
 

‎hyper-schema.json

+14-11
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
"id": "http://json-schema.org/draft/hyper-schema#",
44
"title": "JSON Hyper-Schema",
55
"allOf": [
6-
{"$ref": "http://json-schema.org/draft-04/schema#"}
6+
{"$ref": "http://json-schema.org/draft/schema#"}
77
],
88
"properties": {
99
"additionalItems": {
@@ -48,7 +48,8 @@
4848

4949
"base": {
5050
"description": "URI Template resolved as for the 'href' keyword in the Link Description Object. The resulting URI Reference is resolved against the current URI base and sets the new URI base for URI references within the instance.",
51-
"type": "string"
51+
"type": "string",
52+
"format": "uritemplate"
5253
},
5354
"links": {
5455
"type": "array",
@@ -80,7 +81,13 @@
8081
"properties": {
8182
"href": {
8283
"description": "a URI template, as defined by RFC 6570, with the addition of the $, ( and ) characters for pre-processing",
83-
"type": "string"
84+
"type": "string",
85+
"format": "uritemplate"
86+
},
87+
"hrefVars": {
88+
"description": "an object where each property is a variable name from \"href\" and the value is a schema describing the data needed to fill in the variable.",
89+
"type": "object",
90+
"additionalProperties": {"$ref": "#"}
8491
},
8592
"rel": {
8693
"description": "relation to the target resource of the link",
@@ -92,24 +99,20 @@
9299
},
93100
"targetSchema": {
94101
"description": "JSON Schema describing the link target",
95-
"$ref": "#"
102+
"allOf": [{"$ref": "#"}]
96103
},
97104
"mediaType": {
98105
"description": "media type (as defined by RFC 2046) describing the link target",
99106
"type": "string"
100107
},
101-
"method": {
102-
"description": "specifies that the client can construct a templated query (\"get\") or non-idempotent request (\"post\") to a resource.",
103-
"type": "string"
104-
},
105108
"encType": {
106-
"description": "The media type in which to submit data along with the request",
109+
"description": "The media type in which to submit data in the request body",
107110
"type": "string",
108111
"default": "application/json"
109112
},
110113
"schema": {
111-
"description": "Schema describing the data to submit along with the request",
112-
"$ref": "#"
114+
"description": "Schema describing the data to submit in the request body"},
115+
"allOf": [{"$ref": "#"}]
113116
}
114117
}
115118
}

‎jsonschema-hyperschema.xml

+177-164
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
<!ENTITY rfc5988 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.5988.xml">
1010
<!ENTITY rfc6570 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.6570.xml">
1111
<!ENTITY rfc7231 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.7231.xml">
12+
<!ENTITY rfc7409 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.7409.xml">
1213
<!ENTITY html5 SYSTEM "http://xml.resource.org/public/rfc/bibxml4/reference.W3C.CR-html5-20140731.xml">
1314
]>
1415
<?rfc toc="yes"?>
@@ -364,151 +365,172 @@
364365
</t>
365366

366367
<!-- Possibly include a short section on motivations, including triples, resources, and progressive disclosure -->
367-
368-
<section title="href" anchor="href">
369-
<t>
370-
The value of the "href" link description property is a template used to determine the target URI of the related resource.
371-
The value of the instance property MUST be resolved as a <xref target="RFC3986">URI-reference</xref> against the base URI of the instance.
372-
</t>
373-
<t>
374-
This property is REQUIRED.
375-
</t>
376-
377-
<section title="URI Templating">
368+
<section title="URI Templating">
369+
<section title="href" anchor="href">
378370
<t>
379-
The value of "href" is to be used as a URI Template, as defined in <xref target="RFC6570">RFC 6570</xref>. However, some special considerations apply:
371+
The value of the "href" link description property is a template
372+
used to determine the target URI of the related resource.
380373
</t>
381-
382-
<section title="Pre-processing">
383-
<t>
384-
<cref>This pre-processing section is subject to significant change in upcoming drafts.</cref>
385-
</t>
386-
<t>
387-
The <xref target="RFC6570">URI Template specification</xref> restricts the set of characters available for variable names.
388-
Property names in JSON, however, can be any UTF-8 string.
389-
</t>
390-
391-
<t>
392-
To allow the use of any JSON property name in the template, before using the value of "href" as a URI Template, the following pre-processing rules MUST be applied, in order:
393-
</t>
394-
395-
<section title="Bracket escaping">
396-
<t>
397-
The purpose of this step is to allow the use of brackets to percent-encode variable names inside curly brackets.
398-
Variable names to be escaped are enclosed within rounded brackets, with the close-rounded-bracket character ")" being escaped as a pair of close-rounded-brackets "))".
399-
Since the empty string is not a valid variable name in RFC 6570, an empty pair of brackets is replaced with "%65mpty".
400-
</t>
401-
402-
<t>
403-
The rules are as follows:
404-
</t>
405-
406-
<t>
407-
Find the largest possible sections of the text such that:
408-
<list>
409-
<t>do not contain an odd number of close-rounded-bracket characters ")" in sequence in that section of the text</t>
410-
<t>are surrounded by a pair of rounded brackets: ( ), where</t>
411-
<t>the surrounding rounded brackets are themselves contained within a pair of curly brackets: { }</t>
412-
</list>
413-
</t>
414-
<t>
415-
Each of these sections of the text (including the surrounding rounded brackets) MUST be replaced, according to the following rules:
416-
<list>
417-
<t>If the brackets contained no text (the empty string), then they are replaced with "%65mpty" (which is "empty" with a percent-encoded "e")</t>
418-
<t>Otherwise, the enclosing brackets are removed, and the inner text used after the following modifications
419-
<list>
420-
<t>all pairs of close-brackets "))" are replaced with a single close bracket</t>
421-
<t>after that, the text is replaced with its percent-encoded equivalent, such that the result is a valid RFC 6570 variable name (note that this requires encoding characters such as "*" and "!")</t>
422-
</list>
423-
</t>
424-
</list>
425-
</t>
426-
</section>
427-
428-
<section title="Replacing $">
429-
<t>
430-
After the above substitutions, if the character "$" (dollar sign) appears within a pair of curly brackets, then it MUST be replaced with the text "%73elf" (which is "self" with a percent-encoded "s").
431-
</t>
432-
<t>
433-
The purpose of this stage is to allow the use of the instance value itself (instead of its object properties or array items) in the URI Template, by the special value "%73elf".
434-
</t>
435-
</section>
436-
437-
<section title="Choice of special-case values">
438-
<t>
439-
The special-case values of "%73elf" and "%65mpty" were chosen because they are unlikely to be accidentally generated by either a human or automated escaping.
440-
</t>
441-
</section>
442-
443-
<section title="Examples">
444-
<texttable>
445-
<preamble>For example, here are some possible values for "href", followed by the results after pre-processing:</preamble>
446-
<ttcol>Input</ttcol>
447-
<ttcol>Output</ttcol>
448-
<c>"no change"</c> <c>"no change"</c>
449-
<c>"(no change)"</c> <c>"(no change)"</c>
450-
<c>"{(escape space)}"</c> <c>"{escape%20space}"</c>
451-
<c>"{(escape+plus)}"</c> <c>"{escape%2Bplus}"</c>
452-
<c>"{(escape*asterisk)}"</c> <c>"{escape%2Aasterisk}"</c>
453-
<c>"{(escape(bracket)}"</c> <c>"{escape%28bracket}"</c>
454-
<c>"{(escape))bracket)}"</c> <c>"{escape%29bracket}"</c>
455-
<c>"{(a))b)}"</c> <c>"{a%29b}</c>
456-
<c>"{(a (b)))}"</c> <c>"{a%20%28b%29}</c>
457-
<c>"{()}"</c> <c>"{%65mpty}</c>
458-
<c>"{+$*}"</c> <c>"{+%73elf*}</c>
459-
<c>"{+($)*}"</c> <c>"{+%24*}</c>
460-
<postamble>
461-
Note that in the final example, because the "+" was outside the brackets, it remained unescaped, whereas in the fourth example the "+" was escaped.
462-
</postamble>
463-
</texttable>
464-
</section>
465-
</section>
466-
467-
<section title="Values for substitution">
468-
<t>
469-
After pre-processing, the URI Template is filled out using data from the instance.
470-
To allow the use of any object property (including the empty string), array index, or the instance value itself, the following rules are defined:
471-
</t>
472-
374+
<t>
375+
The value of "href" is to be used as a URI Template, as defined in
376+
<xref target="RFC6570">RFC 6570</xref>. Template variables are
377+
filled out using data from the identically named property of the
378+
instance, or with user input conforming to schemas defined by the
379+
<xref target="href-vars">"hrefVars"</xref> keyword.
380+
</t>
381+
<t>
382+
After the template is filled out, the resulting value MUST be
383+
resolved as a <xref target="RFC3986">URI-reference</xref> against
384+
the base URI of the instance.
385+
</t>
386+
<t>
387+
This property is REQUIRED.
388+
</t>
389+
</section>
390+
<section title="hrefVars" anchor="href-vars">
391+
<t>
392+
The value of the "hrefVars" link description property MUST be an object.
393+
The property names in the object SHOULD each be identical to a template
394+
variable from the "href" value in the same link description.
395+
The value of each property MUST be a valid JSON Schema.
396+
</t>
397+
<t>
398+
Template variables from "href" which do not appear as properties can be
399+
considered to be present with an empty schema.
400+
</t>
401+
<t>
402+
Schema authors can prevent user input for a template variable by
403+
setting its schema to false in "hrefVars". Implementations MUST NOT
404+
attempt to validate values resolved from instance data with
405+
"hrefVars".
406+
</t>
407+
<figure>
408+
<preamble>
409+
For example, this defines a schema for each of the query string
410+
parameters in the URI template:
411+
</preamble>
412+
<artwork>
413+
<![CDATA[{
414+
"href": "/foos{?condition,count,query}",
415+
"hrefVars": {
416+
"condition": {
417+
"type": "boolean",
418+
"default": true
419+
},
420+
"count": {
421+
"type": "integer",
422+
"minimum": 0,
423+
"default": 0
424+
},
425+
"query": {
426+
"type": "string"
427+
}
428+
}
429+
}]]>
430+
</artwork>
431+
</figure>
432+
<figure>
433+
<preamble>
434+
In this example, the schema for "extra" is given as a reference
435+
to keep the user input validation constraints identical to the
436+
instance validation constraints for the corresponding property,
437+
while "id" is given a false schema to prevent user input for
438+
that variable.
439+
</preamble>
440+
<artwork>
441+
<![CDATA[{
442+
"definitions": {
443+
"extra": {
444+
"type": "string",
445+
"maxLength": 32
446+
}
447+
},
448+
"type": "object",
449+
"properties": {
450+
"id": {
451+
"type": "integer",
452+
"minimum": 1,
453+
"readOnly": true
454+
},
455+
"extra": {"$ref": "#/definitions/extra"}
456+
},
457+
"links": [{
458+
"rel": "self",
459+
"href": "/things/{id}{?extra}",
460+
"hrefVars": {
461+
"id": false,
462+
"extra": {"$ref": "#/definitions/extra"}
463+
}
464+
}]
465+
}]]>
466+
</artwork>
467+
</figure>
468+
</section>
469+
<section title="Values for substitution">
470+
<t>
471+
For each variable in the URI Template, if no user input was
472+
provided, the variable MUST be filled out using the value of
473+
the corresponding instance property (if it exists).
474+
</t>
475+
<section title="Converting to strings">
473476
<t>
474-
For a given variable name in the URI Template, the value to use is determined as follows:
477+
When any value provided for a URI template variable is null,
478+
a boolean or a number, then it should first be converted into
479+
a string as follows:
475480
<list>
476-
<t>If the variable name is "%73elf", then the instance value itself MUST be used.</t>
477-
<t>If the variable name is "%65mpty", then the instances's empty-string ("") property MUST be used (if it exists).</t>
478-
<t>If the instance is an array, and the variable name is a representation of a non-negative integer, then the value at the corresponding array index MUST be used (if it exists).</t>
479-
<t>Otherwise, the variable name should be percent-decoded, and the corresponding object property MUST be used (if it exists).</t>
481+
<t>null values SHOULD be replaced by the text "null"</t>
482+
<t>boolean values SHOULD be replaced by their lower-case equivalents: "true" or "false"</t>
483+
<t>numbers SHOULD be replaced with their original JSON representation.</t>
480484
</list>
481485
</t>
482-
483-
<section title="Converting to strings">
484-
<t>
485-
When any value referenced by the URI template is null, a boolean or a number, then it should first be converted into a string as follows:
486-
<list>
487-
<t>null values SHOULD be replaced by the text "null"</t>
488-
<t>boolean values SHOULD be replaced by their lower-case equivalents: "true" or "false"</t>
489-
<t>numbers SHOULD be replaced with their original JSON representation.</t>
490-
</list>
491-
</t>
492-
<t>
493-
In some software environments the original JSON representation of a number will not be available (there is no way to tell the difference between 1.0 and 1), so any reasonable representation should be used.
494-
Schema and API authors should bear this in mind, and use other types (such as string or boolean) if the exact representation is important.
495-
</t>
496-
</section>
486+
<t>
487+
In some software environments the original JSON representation of a number will not be available (there is no way to tell the difference between 1.0 and 1), so any reasonable representation should be used.
488+
Schema and API authors should bear this in mind, and use other types (such as string or boolean) if the exact representation is important.
489+
</t>
497490
</section>
498491

499492
<section title="Missing values">
500493
<t>
501-
Sometimes, the appropriate values will not be available.
494+
Sometimes, the appropriate values will not be available and no
495+
user input will have been provided.
502496
For example, the template might specify the use of object properties, but the instance is an array or a string.
503497
</t>
504498

505499
<t>
506-
If any of the values required for the template are not present in the JSON instance, then substitute values MAY be provided from another source (such as default values).
507-
Otherwise, the link definition SHOULD be considered not to apply to the instance.
500+
In such cases, the link definition SHOULD be considered not to apply to the instance.
508501
</t>
509502
</section>
510503
</section>
511504

505+
<section title="Limitations">
506+
<t><cref>
507+
It is intended that these limitations will be removed in a future
508+
draft. While some were previously handled by URI Template
509+
pre-processing, many were not. The pre-processing rules were
510+
a significant implementation burden and do not seem to have been
511+
adopted broadly if at all, so they have been removed.
512+
</cref></t>
513+
<t>
514+
The <xref target="RFC6570">URI Template specification</xref>
515+
restricts the set of characters available for variable names.
516+
Property names in JSON, however, can be any UTF-8 string.
517+
Currently, such properties cannot be used with URI Templates.
518+
</t>
519+
<t>
520+
Additionally, JSON instances can be of types other than objects
521+
or arrays, can have complex child instances, and can be contained
522+
within an object or an array. Instance data other than immediate
523+
object properties and array elements cannot currently be used
524+
with URI Templates.
525+
</t>
526+
<t>
527+
In particular, a dot-separated URI template variable name
528+
MUST NOT be considered to reference nested properties.
529+
Dot-separated names cannot access all possible instance data
530+
locations, so a different mechanism may be chosen for this
531+
functionality in a future draft.
532+
</t>
533+
</section>
512534
</section>
513535

514536
<section title="rel">
@@ -772,67 +794,55 @@ GET /foo/
772794
</section>
773795
</section>
774796

775-
<section title="Submission Form Properties">
797+
<section title="Submission Properties">
776798
<t>
777-
The following properties also apply to Link Description Objects, and provide functionality analogous to <xref target="W3C.CR-html5-20140731">HTML forms</xref>, by providing a means for making a request with client- or user-selected information.
799+
The following properties also apply to Link Description Objects, and provide functionality analogous to sending an <xref target="W3C.CR-html5-20140731">HTML forms</xref> in a request body, by providing a means for making a request with client- or user-selected information.
800+
</t>
801+
<t>
802+
For an analogue to encoding HTML forms in the request URI, see
803+
<xref target="href-vars">"hrefVars"</xref>.
778804
</t>
779-
780-
<section title="method">
781-
<t>
782-
This property specifies that the client can construct a templated query or non-idempotent request to a resource.
783-
</t>
784-
<t>
785-
If "method" is "get", the link identifies how a user can compute the URI of an arbitrary resource. For example, how compute a link to a page of search results relating to the instance, for a user-selected query term. Despite being named after GET, there is no constraint on the method or protocol used to interact with the remote resource.
786-
</t>
787-
<t>
788-
If "method" is "post", the link specifies how a user can construct a document to submit to the link target for evaluation.
789-
</t>
790-
<t>
791-
Values for this property SHOULD be lowercase, and SHOULD be compared case-insensitive. Use of other values not defined here SHOULD be ignored.
792-
</t>
793-
</section>
794805

795806
<section title="encType">
796807
<t>
797-
If present, this property indicates the media type format the client should use to encode a query parameter or send to the server. posting to the collection of instances at the target resource.
798-
If the method is "get", this will indicate how to encode the query-string that is appended to the "href" link target.
799-
If the method is "post", this indicates which media type to send to the server and how to encode it.
800-
808+
If present, this property indicates the media type format the client should use to encode a document to send to the server in the request body.
801809
<figure>
802810
<preamble>For example, with the following schema:</preamble>
803811
<artwork>
804812
<![CDATA[{
805813
"links": [{
806-
"encType": "application/x-www-form-urlencoded",
807-
"method": "get",
814+
"encType": "application/cbor",
808815
"href": "/Product/",
809816
"properties": {
810817
"name": {
811-
"description": "name of the product"
818+
"description": "name of the product",
819+
"type": "string"
820+
},
821+
"features": {
822+
"description": "features supported by the product",
823+
"type": "array",
824+
"items": {
825+
"$ref": "http://example.com/schema#feature"
826+
}
812827
}
813828
}
814829
}]
815830
}]]>
816831
</artwork>
817-
<postamble>This indicates that the client can query the server for instances that have a specific name.</postamble>
818-
</figure>
819-
820-
<figure>
821-
<preamble>For example:</preamble>
822-
<artwork>
823-
<![CDATA[
824-
/Product/?name=Slinky
825-
]]>
826-
</artwork>
832+
<postamble>
833+
This indicates that the client can submit a name and a list
834+
of features to a product resource, which should be encoded
835+
as <xref target="RFC7409">CBOR</xref>.
836+
</postamble>
827837
</figure>
828-
829-
If the method is "post", "application/json" is the default media type.
830838
</t>
831839
</section>
832840

833841
<section title="schema">
834842
<t>
835-
This property contains a schema which defines the acceptable structure of the document being encoded according to the "encType" property.
843+
This property contains a schema which defines the acceptable
844+
structure of the document being encoded according to the "encType"
845+
property for submission in the request body.
836846
</t>
837847

838848
<t>
@@ -874,6 +884,7 @@ GET /foo/
874884
<!--&rfc5226;-->
875885
&rfc5988;
876886
&rfc7231;
887+
&rfc7409;
877888
&html5;
878889
</references>
879890

@@ -907,6 +918,8 @@ GET /foo/
907918
<t hangText="draft-wright-json-schema-hyperschema-01">
908919
<list style="symbols">
909920
<t>Fixed examples</t>
921+
<t>Added "hrefVars" keyword for URI input</t>
922+
<t>Removed "method" and reserved "schema" and "encType" for request bodies</t>
910923
</list>
911924
</t>
912925
<t hangText="draft-wright-json-schema-hyperschema-00">

‎links.json

+44
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
{
2+
"$schema": "http://json-schema.org/draft/hyper-schema#",
3+
"id": "http://json-schema.org/draft/links#",
4+
"title": "Link Description Object",
5+
"type": "object",
6+
"required": [ "href"],
7+
"properties": {
8+
"href": {
9+
"description": "a URI template, as defined by RFC 6570, with the addition of the $, ( and ) characters for pre-processing",
10+
"type": "string",
11+
"format": "uritemplate"
12+
},
13+
"hrefVars": {
14+
"description": "an object where each property is a variable name from \"href\" and the value is a schema describing the data needed to fill in the variable.",
15+
"type": "object",
16+
"additionalProperties": {"$ref": "hyper-schema#"}
17+
},
18+
"rel": {
19+
"description": "relation to the target resource of the link",
20+
"type": "string"
21+
},
22+
"title": {
23+
"description": "a title for the link",
24+
"type": "string"
25+
},
26+
"targetSchema": {
27+
"description": "JSON Schema describing the link target",
28+
"allOf": [{"$ref": "hyper-schema#"}]
29+
},
30+
"mediaType": {
31+
"description": "media type (as defined by RFC 2046) describing the link target",
32+
"type": "string"
33+
},
34+
"encType": {
35+
"description": "The media type in which to submit data in the request body",
36+
"type": "string",
37+
"default": "application/json"
38+
},
39+
"schema": {
40+
"description": "Schema describing the data to submit in the request body",
41+
"allOf": [{"$ref": "hyper-schema#"}]
42+
}
43+
}
44+
}

0 commit comments

Comments
 (0)
Please sign in to comment.