diff --git a/hyper-schema.json b/hyper-schema.json index b633bd50..58b551ce 100644 --- a/hyper-schema.json +++ b/hyper-schema.json @@ -18,7 +18,12 @@ "properties": { "href": { "description": "a URI template, as defined by RFC 6570, with the addition of the $, ( and ) characters for pre-processing", - "type": "string" + "type": "string", + "format": "uritemplate" + }, + "hrefSchema": { + "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": "#"} ] }, "rel": { "description": "relation to the target resource of the link", @@ -36,10 +41,6 @@ "description": "media type (as defined by RFC 2046) describing the link target", "type": "string" }, - "method": { - "description": "specifies that the client can construct a templated query (\"get\") or non-idempotent request (\"post\") to a resource.", - "type": "string" - }, "encType": { "description": "The media type in which to submit data along with the request", "type": "string", @@ -96,7 +97,8 @@ "base": { "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.", - "type": "string" + "type": "string", + "format": "uritemplate" }, "links": { "type": "array", diff --git a/jsonschema-hyperschema.xml b/jsonschema-hyperschema.xml index 34504636..cb4ff020 100644 --- a/jsonschema-hyperschema.xml +++ b/jsonschema-hyperschema.xml @@ -9,6 +9,7 @@ + ]> @@ -371,151 +372,182 @@ - -
- - The value of the "href" link description property is a template used to determine the target URI of the related resource. - The value of the instance property MUST be resolved as a URI-reference against the base URI of the instance. - - - This property is REQUIRED. - - -
+
+
- The value of "href" is to be used as a URI Template, as defined in RFC 6570. However, some special considerations apply: + The value of the "href" link description property is a template + used to determine the target URI of the related resource. - -
- - This pre-processing section is subject to significant change in upcoming drafts. - - - The URI Template specification restricts the set of characters available for variable names. - Property names in JSON, however, can be any UTF-8 string. - - - - 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: - - -
- - The purpose of this step is to allow the use of brackets to percent-encode variable names inside curly brackets. - 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 "))". - Since the empty string is not a valid variable name in RFC 6570, an empty pair of brackets is replaced with "%65mpty". - - - - The rules are as follows: - - - - Find the largest possible sections of the text such that: - - do not contain an odd number of close-rounded-bracket characters ")" in sequence in that section of the text - are surrounded by a pair of rounded brackets: ( ), where - the surrounding rounded brackets are themselves contained within a pair of curly brackets: { } - - - - Each of these sections of the text (including the surrounding rounded brackets) MUST be replaced, according to the following rules: - - If the brackets contained no text (the empty string), then they are replaced with "%65mpty" (which is "empty" with a percent-encoded "e") - Otherwise, the enclosing brackets are removed, and the inner text used after the following modifications - - all pairs of close-brackets "))" are replaced with a single close bracket - 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 "!") - - - - -
- -
- - 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"). - - - 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". - -
- -
- - 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. - -
- -
- - For example, here are some possible values for "href", followed by the results after pre-processing: - Input - Output - "no change" "no change" - "(no change)" "(no change)" - "{(escape space)}" "{escape%20space}" - "{(escape+plus)}" "{escape%2Bplus}" - "{(escape*asterisk)}" "{escape%2Aasterisk}" - "{(escape(bracket)}" "{escape%28bracket}" - "{(escape))bracket)}" "{escape%29bracket}" - "{(a))b)}" "{a%29b} - "{(a (b)))}" "{a%20%28b%29} - "{()}" "{%65mpty} - "{+$*}" "{+%73elf*} - "{+($)*}" "{+%24*} - - Note that in the final example, because the "+" was outside the brackets, it remained unescaped, whereas in the fourth example the "+" was escaped. - - -
-
- -
- - After pre-processing, the URI Template is filled out using data from the instance. - To allow the use of any object property (including the empty string), array index, or the instance value itself, the following rules are defined: - - + + The value of "href" is to be used as a URI Template, as defined in + RFC 6570. Template variables are + filled out using data from the identically named property of the + instance, or with user input conforming to schema defined by the + "hrefSchema" keyword. + + + After the template is filled out, the resulting value MUST be + resolved as a URI-reference against + the base URI of the instance. + + + This property is REQUIRED. + +
+
+ + The value of the "hrefSchema" link description property MUST be + a valid JSON Schema. This schema is used to validate user input + for filling out the URI Template in "href". + + + To validate user input, the supplied data MUST be considered + as a JSON object where the property names are the template + variables for which user input has been supplied, and the + values are the user-supplied values. + + + Setting the entire "hrefSchema" schema to "false" prevents + any user input from being accepted. + + + Implementations MUST NOT attempt to validate values resolved from + instance data with "hrefSchema". This allows for different + validation rules for user input, such as supporting spelled-out + months for date-time input but using the standard date-time + format for storage. + +
+ + For example, this defines a schema for each of the query string + parameters in the URI template: + + + + +
+
+ + In this example, the schema for "extra" is given as a reference + to keep the user input validation constraints identical to the + instance validation constraints for the corresponding property, + while "id" is given a false schema to prevent user input for + that variable. + + + + +
+
+
+ + For each variable in the URI Template, if no user input was + provided, the variable MUST be filled out using the value of + the corresponding instance property (if it exists). + +
- For a given variable name in the URI Template, the value to use is determined as follows: + When any value provided for a URI template variable is null, + a boolean or a number, then it should first be converted into + a string as follows: - If the variable name is "%73elf", then the instance value itself MUST be used. - If the variable name is "%65mpty", then the instances's empty-string ("") property MUST be used (if it exists). - 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). - Otherwise, the variable name should be percent-decoded, and the corresponding object property MUST be used (if it exists). + null values SHOULD be replaced by the text "null" + boolean values SHOULD be replaced by their lower-case equivalents: "true" or "false" + numbers SHOULD be replaced with their original JSON representation. - -
- - 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: - - null values SHOULD be replaced by the text "null" - boolean values SHOULD be replaced by their lower-case equivalents: "true" or "false" - numbers SHOULD be replaced with their original JSON representation. - - - - 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. - Schema and API authors should bear this in mind, and use other types (such as string or boolean) if the exact representation is important. - -
+ + 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. + Schema and API authors should bear this in mind, and use other types (such as string or boolean) if the exact representation is important. +
- Sometimes, the appropriate values will not be available. + Sometimes, the appropriate values will not be available and no + user input will have been provided. For example, the template might specify the use of object properties, but the instance is an array or a string. - 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). - Otherwise, the link definition SHOULD be considered not to apply to the instance. + In such cases, the link definition SHOULD be considered not to apply to the instance.
+
+ + It is intended that these limitations will be removed in a future + draft. While some were previously handled by URI Template + pre-processing, many were not. The pre-processing rules were + a significant implementation burden and do not seem to have been + adopted broadly if at all, so they have been removed. + + + The URI Template specification + restricts the set of characters available for variable names. + Property names in JSON, however, can be any UTF-8 string. + Currently, such properties cannot be used with URI Templates. + + + Additionally, JSON instances can be of types other than objects + or arrays, can have complex child instances, and can be contained + within an object or an array. Instance data other than immediate + object properties and array elements cannot currently be used + with URI Templates. + + + In particular, a dot-separated URI template variable name + MUST NOT be considered to reference nested properties. + Dot-separated names cannot access all possible instance data + locations, so a different mechanism may be chosen for this + functionality in a future draft. + +
@@ -779,69 +811,57 @@ GET /foo/
-
+
- The following properties also apply to Link Description Objects, and provide functionality analogous to HTML forms, by providing a means for making a request with client- or user-selected information. + The following properties also apply to Link Description Objects, and provide functionality analogous to sending an HTML forms in a request body, by providing a means for making a request with client- or user-selected information. + + + For an analogue to encoding HTML forms in the request URI, see + "hrefSchema". - -
- - This property specifies that the client can construct a templated query or non-idempotent request to a resource. - - - 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. - - - If "method" is "post", the link specifies how a user can construct a document to submit to the link target for evaluation. - - - Values for this property SHOULD be lowercase, and SHOULD be compared case-insensitive. Use of other values not defined here SHOULD be ignored. - -
- 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. - If the method is "get", this will indicate how to encode the query-string that is appended to the "href" link target. - If the method is "post", this indicates which media type to send to the server and how to encode it. - + 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.
For example, with the following schema: - This indicates that the client can query the server for instances that have a specific name. -
- -
- For example: - - - + + This indicates that the client can submit a name and a list + of features to a product resource, which should be encoded + as CBOR. +
- - If the method is "post", "application/json" is the default media type.
- This property contains a schema which defines the acceptable structure of the document being encoded according to the "encType" property. + This property contains a schema which defines the acceptable + structure of the document being encoded according to the "encType" + property for submission in the request body. @@ -882,6 +902,7 @@ GET /foo/ &rfc2046; &rfc5988; + &rfc7049; &rfc7231; &html5; @@ -916,6 +937,8 @@ GET /foo/ Fixed examples + Added "hrefSchema" keyword for URI input + Removed "method" and reserved "schema" and "encType" for request bodies diff --git a/links.json b/links.json index 3c9cd1c6..92222fa1 100644 --- a/links.json +++ b/links.json @@ -7,7 +7,12 @@ "properties": { "href": { "description": "a URI template, as defined by RFC 6570, with the addition of the $, ( and ) characters for pre-processing", - "type": "string" + "type": "string", + "format": "uritemplate" + }, + "hrefSchema": { + "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": "#"} ] }, "rel": { "description": "relation to the target resource of the link", @@ -25,10 +30,6 @@ "description": "media type (as defined by RFC 2046) describing the link target", "type": "string" }, - "method": { - "description": "specifies that the client can construct a templated query (\"get\") or non-idempotent request (\"post\") to a resource.", - "type": "string" - }, "encType": { "description": "The media type in which to submit data along with the request", "type": "string",