idnits 2.17.1 draft-handrews-json-schema-hyperschema-01.txt: Checking boilerplate required by RFC 5378 and the IETF Trust (see https://trustee.ietf.org/license-info): ---------------------------------------------------------------------------- No issues found here. Checking nits according to https://www.ietf.org/id-info/1id-guidelines.txt: ---------------------------------------------------------------------------- No issues found here. Checking nits according to https://www.ietf.org/id-info/checklist : ---------------------------------------------------------------------------- ** The document seems to lack an IANA Considerations section. (See Section 2.2 of https://www.ietf.org/id-info/checklist for how to handle the case when there are no actions for IANA.) Miscellaneous warnings: ---------------------------------------------------------------------------- == The copyright year in the IETF Trust and authors Copyright Line does not match the current year == The document seems to use 'NOT RECOMMENDED' as an RFC 2119 keyword, but does not include the phrase in its RFC 2119 key words list. -- The document date (January 19, 2018) is 2287 days in the past. Is this intentional? Checking references for intended status: Informational ---------------------------------------------------------------------------- -- Looks like a reference, but probably isn't: '456' on line 1680 == Outdated reference: A later version (-15) exists of draft-reschke-http-jfv-06 -- Obsolete informational reference (is this intentional?): RFC 7230 (Obsoleted by RFC 9110, RFC 9112) -- Obsolete informational reference (is this intentional?): RFC 7231 (Obsoleted by RFC 9110) -- Obsolete informational reference (is this intentional?): RFC 7807 (Obsoleted by RFC 9457) Summary: 1 error (**), 0 flaws (~~), 3 warnings (==), 5 comments (--). Run idnits with the --verbose option for more detailed information about the items above. -------------------------------------------------------------------------------- 2 Internet Engineering Task Force H. Andrews, Ed. 3 Internet-Draft Cloudflare, Inc. 4 Intended status: Informational A. Wright, Ed. 5 Expires: July 23, 2018 January 19, 2018 7 JSON Hyper-Schema: A Vocabulary for Hypermedia Annotation of JSON 8 draft-handrews-json-schema-hyperschema-01 10 Abstract 12 JSON Schema is a JSON-based format for describing JSON data using 13 various vocabularies. This document specifies a vocabulary for 14 annotating JSON documents with hyperlinks. These hyperlinks include 15 attributes describing how to manipulate and interact with remote 16 resources through hypermedia environments such as HTTP, as well as 17 determining whether the link is usable based on the instance value. 18 The hyperlink serialization format described in this document is also 19 usable independent of JSON Schema. 21 Note to Readers 23 The issues list for this draft can be found at . 26 For additional information, see . 28 To provide feedback, use this issue tracker, the communication 29 methods listed on the homepage, or email the document editors. 31 Status of This Memo 33 This Internet-Draft is submitted in full conformance with the 34 provisions of BCP 78 and BCP 79. 36 Internet-Drafts are working documents of the Internet Engineering 37 Task Force (IETF). Note that other groups may also distribute 38 working documents as Internet-Drafts. The list of current Internet- 39 Drafts is at https://datatracker.ietf.org/drafts/current/. 41 Internet-Drafts are draft documents valid for a maximum of six months 42 and may be updated, replaced, or obsoleted by other documents at any 43 time. It is inappropriate to use Internet-Drafts as reference 44 material or to cite them other than as "work in progress." 46 This Internet-Draft will expire on July 23, 2018. 48 Copyright Notice 50 Copyright (c) 2018 IETF Trust and the persons identified as the 51 document authors. All rights reserved. 53 This document is subject to BCP 78 and the IETF Trust's Legal 54 Provisions Relating to IETF Documents 55 (https://trustee.ietf.org/license-info) in effect on the date of 56 publication of this document. Please review these documents 57 carefully, as they describe your rights and restrictions with respect 58 to this document. Code Components extracted from this document must 59 include Simplified BSD License text as described in Section 4.e of 60 the Trust Legal Provisions and are provided without warranty as 61 described in the Simplified BSD License. 63 Table of Contents 65 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 3 66 2. Notational Conventions . . . . . . . . . . . . . . . . . . . 4 67 3. Overview . . . . . . . . . . . . . . . . . . . . . . . . . . 4 68 3.1. Terminology . . . . . . . . . . . . . . . . . . . . . . . 5 69 3.2. Functionality . . . . . . . . . . . . . . . . . . . . . . 6 70 4. Meta-Schemas and Output Schema . . . . . . . . . . . . . . . 7 71 5. Schema Keywords . . . . . . . . . . . . . . . . . . . . . . . 7 72 5.1. base . . . . . . . . . . . . . . . . . . . . . . . . . . 8 73 5.2. links . . . . . . . . . . . . . . . . . . . . . . . . . . 8 74 6. Link Description Object . . . . . . . . . . . . . . . . . . . 8 75 6.1. Link Context . . . . . . . . . . . . . . . . . . . . . . 9 76 6.1.1. anchor . . . . . . . . . . . . . . . . . . . . . . . 9 77 6.1.2. anchorPointer . . . . . . . . . . . . . . . . . . . . 9 78 6.2. Link Relation Type . . . . . . . . . . . . . . . . . . . 10 79 6.2.1. rel . . . . . . . . . . . . . . . . . . . . . . . . . 10 80 6.2.2. "self" Links . . . . . . . . . . . . . . . . . . . . 10 81 6.2.3. "collection" and "item" Links . . . . . . . . . . . . 11 82 6.2.4. Using Extension Relation Types . . . . . . . . . . . 11 83 6.3. Link Target . . . . . . . . . . . . . . . . . . . . . . . 11 84 6.3.1. href . . . . . . . . . . . . . . . . . . . . . . . . 12 85 6.4. Adjusting URI Template Resolution . . . . . . . . . . . . 12 86 6.4.1. templatePointers . . . . . . . . . . . . . . . . . . 12 87 6.4.2. templateRequired . . . . . . . . . . . . . . . . . . 12 88 6.5. Link Target Attributes . . . . . . . . . . . . . . . . . 12 89 6.5.1. title . . . . . . . . . . . . . . . . . . . . . . . . 13 90 6.5.2. description . . . . . . . . . . . . . . . . . . . . . 13 91 6.5.3. targetMediaType . . . . . . . . . . . . . . . . . . . 13 92 6.5.4. targetSchema . . . . . . . . . . . . . . . . . . . . 14 93 6.5.5. targetHints . . . . . . . . . . . . . . . . . . . . . 14 94 6.6. Link Input . . . . . . . . . . . . . . . . . . . . . . . 15 95 6.6.1. hrefSchema . . . . . . . . . . . . . . . . . . . . . 15 96 6.6.2. headerSchema . . . . . . . . . . . . . . . . . . . . 16 97 6.6.3. Manipulating the Target Resource Representation . . . 16 98 6.6.4. Submitting Data for Processing . . . . . . . . . . . 17 99 7. Implementation Requirements . . . . . . . . . . . . . . . . . 18 100 7.1. Link Discovery and Look-Up . . . . . . . . . . . . . . . 19 101 7.2. URI Templating . . . . . . . . . . . . . . . . . . . . . 19 102 7.2.1. Populating Template Data From the Instance . . . . . 21 103 7.2.2. Accepting Input for Template Data . . . . . . . . . . 21 104 7.2.3. Encoding Data as Strings . . . . . . . . . . . . . . 22 105 7.3. Providing Access to LDO Keywords . . . . . . . . . . . . 23 106 7.4. Requests . . . . . . . . . . . . . . . . . . . . . . . . 23 107 7.5. Responses . . . . . . . . . . . . . . . . . . . . . . . . 24 108 7.6. Streaming Parsers . . . . . . . . . . . . . . . . . . . . 25 109 8. JSON Hyper-Schema and HTTP . . . . . . . . . . . . . . . . . 25 110 8.1. One Link Per Target and Relation Type . . . . . . . . . . 26 111 8.2. "targetSchema" and HTTP . . . . . . . . . . . . . . . . . 26 112 8.3. HTTP POST and the "submission*" keywords . . . . . . . . 27 113 8.4. Optimizing HTTP Discoverability With "targetHints" . . . 27 114 8.5. Advertising HTTP Features With "headerSchema" . . . . . . 28 115 8.6. Creating Resources Through Collections . . . . . . . . . 28 116 8.7. Content Negotiation and Schema Evolution . . . . . . . . 29 117 9. Examples . . . . . . . . . . . . . . . . . . . . . . . . . . 29 118 9.1. Entry Point Links, No Templates . . . . . . . . . . . . . 29 119 9.2. Individually Identified Resources . . . . . . . . . . . . 31 120 9.3. Submitting a Payload and Accepting URI Input . . . . . . 32 121 9.4. "anchor", "base" and URI Template Resolution . . . . . . 35 122 9.5. Collections . . . . . . . . . . . . . . . . . . . . . . . 38 123 9.5.1. Pagination . . . . . . . . . . . . . . . . . . . . . 43 124 9.5.2. Creating the First Item . . . . . . . . . . . . . . . 46 125 10. Security Considerations . . . . . . . . . . . . . . . . . . . 47 126 10.1. Target Attributes . . . . . . . . . . . . . . . . . . . 47 127 10.2. "self" Links . . . . . . . . . . . . . . . . . . . . . . 48 128 11. Acknowledgments . . . . . . . . . . . . . . . . . . . . . . . 49 129 12. References . . . . . . . . . . . . . . . . . . . . . . . . . 49 130 12.1. Normative References . . . . . . . . . . . . . . . . . . 49 131 12.2. Informative References . . . . . . . . . . . . . . . . . 50 132 Appendix A. Using JSON Hyper-Schema in APIs . . . . . . . . . . 52 133 A.1. Resource Evolution With Hyper-Schema . . . . . . . . . . 52 134 A.2. Responses and Errors . . . . . . . . . . . . . . . . . . 52 135 A.3. Static Analysis of an API's Hyper-Schemas . . . . . . . . 53 136 Appendix B. ChangeLog . . . . . . . . . . . . . . . . . . . . . 53 137 Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 56 139 1. Introduction 141 JSON Hyper-Schema is a JSON Schema vocabulary for annotating JSON 142 documents with hyperlinks and instructions for processing and 143 manipulating remote JSON resources through hypermedia environments 144 such as HTTP. 146 The term JSON Hyper-Schema is used to refer to a JSON Schema that 147 uses these keywords. The term "hyper-schema" on its own refers to a 148 JSON Hyper-Schema within the scope of this specification. 150 The primary mechanism introduced for specifying links is the Link 151 Description Object (LDO), which is a serialization of the abstract 152 link model defined in RFC 8288, section 2 [RFC8288]. 154 This specification will use the concepts, syntax, and terminology 155 defined by the JSON Schema core [json-schema] and JSON Schema 156 validation [json-schema-validation] specifications. It is advised 157 that readers have a copy of these specifications. 159 2. Notational Conventions 161 The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", 162 "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this 163 document are to be interpreted as described in RFC 2119 [RFC2119]. 165 3. Overview 167 JSON Hyper-Schema makes it possible to build hypermedia systems from 168 JSON documents by describing how to construct hyperlinks from 169 instance data. 171 The combination of a JSON instance document and a valid application/ 172 schema+json hyper-schema for that instance behaves as a single 173 hypermedia representation. By allowing this separation, hyper- 174 schema-based systems can gracefully support applications that expect 175 plain JSON, while providing full hypermedia capabilities for hyper- 176 schema-aware applications and user agents. 178 User agents can detect the presence of hyper-schema by looking for 179 the application/schema+json media type and a "$schema" value that 180 indicates the presence of the hyper-schema vocabulary. A user agent 181 can then use an implementation of JSON Hyper-Schema to provide an 182 interface to the combination of the schema and instance documents as 183 a single logical representation of a resource, just as with any 184 single-document hypermedia representation format. 186 Hyper-schemas allow representations to take up fewer bytes on the 187 wire, and distribute the burden of link construction from the server 188 to each client. A user agent need not construct a link unless a 189 client application requests that link. JSON Hyper-Schema can also be 190 used on the server side to generate other link serializations or 191 representation formats at runtime, or pre-emptively follow links to 192 facilitate server push usage. 194 Here is an example hyper-schema that adds a single link, with the 195 IANA-registered link relation type "self", that is built from an 196 instance with one known object field named "id": 198 { 199 "type": "object", 200 "properties": { 201 "id": { 202 "type": "number", 203 "readOnly": true 204 } 205 }, 206 "links": [ 207 { 208 "rel": "self", 209 "href": "thing/{id}" 210 } 211 ] 212 } 214 If the instance is {"id": 1234}, and its base URI according to RFC 215 3986 section 5.1 [RFC3986], is "https://api.example.com/", then 216 "https://api.example.com/thing/1234" is the resulting link's target 217 URI. 219 3.1. Terminology 221 The terms "schema", "instance", and "meta-schema" are to be 222 interpreted as defined in the JSON Schema core specification 223 [json-schema]. 225 The terms "applicable" and "attached" are to be interpreted as 226 defined in Section 3 of the JSON Schema validation specification 227 [json-schema-validation]. 229 The terms "link", "link context" (or "context"), "link target" (or 230 "target"), and "target attributes" are to be interpreted as defined 231 in Section 2 of RFC 8288 [RFC8288]. 233 The term "user agent" is to be interpreted as defined in Section 2.1 234 of RFC 7230 [RFC7230], generalized to apply to any protocol that may 235 be used in a hypermedia system rather than specifically being an HTTP 236 client. 238 This specification defines the following terms: 240 JSON Hyper-Schema A JSON Schema using the keywords defined by this 241 specification. 243 hyper-schema Within this document, the term "hyper-schema" always 244 refers to a JSON Hyper-Schema 246 link validity A valid link for an instance is one that is applicable 247 to that instance and does not fail any requirement imposed by the 248 keywords in the Link Description Object. 250 generic user agent A user agent which can be used to interact with 251 any resource, from any server, from among the standardized link 252 relations, media types, URI schemes, and protocols that it 253 supports; though it may be extendible to specially handle 254 particular profiles of media types. 256 client application An application which uses a hypermedia system for 257 a specific purpose. Such an application may also be its own user 258 agent, or it may be built on top of a generic user agent. A 259 client application is programmed with knowledge of link relations, 260 media types, URI schemes, protocols, and data structures that are 261 specific to the application's domain. 263 client input Data provided through a user agent, and most often also 264 through a client application. Such data may be requested from a 265 user interactively, or provided before interaction in forms such 266 as command-line arguments, configuration files, or hardcoded 267 values in source code. 269 operation A specific use of a hyperlink, such as making a network 270 request (for a URI with a scheme such as "http://" that indicates 271 a protocol) or otherwise taking action based on a link (reading 272 data from a "data:" URI, or constructing an email message based on 273 a "mailto:" link). For protocols such as HTTP that support 274 multiple methods, each method is considered to be a separate 275 operation on the same link. 277 3.2. Functionality 279 A JSON Hyper-Schema implementation is able to take a hyper-schema, an 280 instance, and in some cases client input, and produce a set of fully 281 resolved valid links. As defined by RFC 8288, section 2 [RFC8288], a 282 link consists of a context, a typed relation, a target, and 283 optionally additional target attributes. 285 The relation type and target attributes are taken directly from each 286 link's Link Description Object. The context and target identifiers 287 are constructed from some combination of URI Templates, instance 288 data, and (in the case of the target identifier) client input. 290 The target is always fully identified by a URI. Due to the lack of a 291 URI fragment identifier syntax for application/json and many other 292 media types that can be used with JSON Hyper-Schema, the context may 293 be only partially identified by a URI. In such cases, the remaining 294 identification will be provided as a JSON Pointer. 296 A few IANA-registered link relation types are given specific 297 semantics in a JSON Hyper-Schema document. A "self" link is used to 298 interact with the resource that the instance document represents, 299 while "collection" and "item" links identify resources for which 300 collection-specific semantics can be assumed. 302 4. Meta-Schemas and Output Schema 304 The current URI for the JSON Hyper-Schema meta-schema is 305 . 307 The link description format (Section 6) can be used without JSON 308 Schema, and use of this format can be declared by referencing the 309 normative link description schema as the schema for the data 310 structure that uses the links. The URI of the normative link 311 description schema is: . 313 JSON Hyper-Schema implementations are free to provide output in any 314 format. However, a specific format is defined for use in the 315 conformance test suite, which is also used to illustrate points in 316 the "Implementation Requirements" (Section 7), and to show the output 317 generated by examples (Section 9). It is RECOMMENDED that 318 implementations be capable of producing output in this format to 319 facilitated testing. The URI of the JSON Schema describing the 320 recommended output format is . 323 5. Schema Keywords 325 Hyper-schema keywords from all schemas that are applicable to a 326 position in an instance, as defined by Section 3 of JSON Schema 327 validation [json-schema-validation], can be used with that instance. 329 When multiple subschemas are applicable to a given sub-instance, all 330 "link" arrays MUST be combined, in any order, into a single set. 331 Each object in the resulting set MUST retain its own list of 332 applicable "base" values, in resolution order, from the same schema 333 and any parent schemas. 335 As with all JSON Schema keywords, all keywords described in this 336 section are optional. The minimal valid JSON Hyper-schema is the 337 blank object. 339 5.1. base 341 If present, this keyword MUST be first resolved as a URI Template 342 (Section 7.2), and then MUST be resolved as a URI Reference against 343 the current URI base of the instance. The result MUST be set as the 344 new URI base for the instance while processing the sub-schema 345 containing "base" and all sub-schemas within it. 347 The process for resolving the "base" template can be different when 348 being resolved for use with "anchor" than when being resolved for use 349 with "href", which is explained in detail in the URI Templating 350 section. 352 5.2. links 354 The "links" property of schemas is used to associate Link Description 355 Objects with instances. The value of this property MUST be an array, 356 and the items in the array must be Link Description Objects, as 357 defined below. 359 6. Link Description Object 361 A Link Description Object (LDO) is a serialization of the abstract 362 link model defined in RFC 8288, section 2 [RFC8288]. As described in 363 that document, a link consists of a context, a relation type, a 364 target, and optionally target attributes. JSON Hyper-Schema's LDO 365 provides all of these, along with additional features using JSON 366 Schema to describe input for use with the links in various ways. 368 Due to the use of URI Templates to identify link contexts and 369 targets, as well as optional further use of client input when 370 identifying targets, an LDO is a link template that may resolve to 371 multiple links when used with a JSON instance document. 373 A specific use of an LDO, typically involving a request and response 374 across a protocol, is referred to as an operation. For many 375 protocols, multiple operations are possible on any given link. The 376 protocol is indicated by the target's URI scheme. Note that not all 377 URI schemes indicate a protocol that can be used for communications, 378 and even resources with URI schemes that do indicate such protocols 379 need not be available over that protocol. 381 A Link Description Object MUST be an object, and the "href" 382 (Section 6.3.1) and "rel" (Section 6.2.1) properties MUST be present. 384 Each keyword is covered briefly in this section, with additional 385 usage explanation and comprehensive examples given later in the 386 document. 388 6.1. Link Context 390 In JSON Hyper-Schema, the link's context resource is, by default, the 391 sub-instance to which it is attached (as defined by Section 3 of the 392 JSON Schema validation specification [json-schema-validation]). This 393 is often not the entire instance document. This default context can 394 be changed using the keywords in this section. 396 Depending on the media type of the instance, it may or may not be 397 possible to assign a URI to the exact default context resource. In 398 particular, application/json does not define a URI fragment 399 resolution syntax, so properties or array elements within a plain 400 JSON document cannot be fully identified by a URI. When it is not 401 possible to produce a complete URI, the position of the context 402 SHOULD be conveyed by the URI of the instance document, together with 403 a separate plain-string JSON Pointer. 405 Implementations MUST be able to construct the link context's URI, and 406 (if necessary for full identification), a JSON Pointer in string 407 representation form as per RFC 6901, section 5 [RFC6901] in place of 408 a URI fragment. The process for constructing a URI based on a URI 409 template is given in the URI Templating (Section 7.2) section. 411 6.1.1. anchor 413 This property sets the context URI of the link. The value of the 414 property is a URI Template [RFC6570], and the resulting URI-reference 415 [RFC3986] MUST be resolved against the base URI of the instance. 417 The URI is computed from the provided URI template using the same 418 process described for the "href" (Section 6.3.1) property, with the 419 exception that "hrefSchema" (Section 6.6.1) MUST NOT be applied. 420 Unlike target URIs, context URIs do not accept user input. 422 6.1.2. anchorPointer 424 This property changes the point within the instance that is 425 considered to be the context resource of the link. The value of the 426 property MUST be a valid JSON Pointer in JSON String representation 427 form, or a valid Relative JSON Pointer [relative-json-pointer] which 428 is evaluated relative to the default context. 430 While an alternate context with a known URI is best set with the 431 "anchor" (Section 6.1.1) keyword, the lack of a fragment identifier 432 syntax for application/json means that it is usually not possible to 433 change the context within a JSON instance using a URI. 435 Even in "+json" media types that define JSON Pointer as a fragment 436 identifier syntax, if the default context is nested within an array, 437 it is not possible to obtain the index of the default context's 438 position in that array in order to construct a pointer to another 439 property in that same nested JSON object. This will be demonstrated 440 in the examples. 442 The result of processing this keyword SHOULD be a URI fragment if the 443 media type of the instance allows for such a fragment. Otherwise it 444 MUST be a string-encoded JSON Pointer. 446 6.2. Link Relation Type 448 The link's relation type identifies its semantics. It is the primary 449 means of conveying how an application can interact with a resource. 451 Relationship definitions are not normally media type dependent, and 452 users are encouraged to utilize the most suitable existing accepted 453 relation definitions. 455 6.2.1. rel 457 The value of this property MUST be a string, and MUST be a single 458 Link Relation Type as defined in RFC 8288, Section 2.1. 460 This property is required. 462 6.2.2. "self" Links 464 A "self" link, as originally defined by Section 4.2.7.2 of RFC 4287 465 [RFC4287], indicates that the target URI identifies a resource 466 equivalent to the link context. In JSON Hyper-Schema, a "self" link 467 MUST be resolvable from the instance, and therefore "hrefSchema" MUST 468 NOT be present. 470 Hyper-schema authors SHOULD use "templateRequired" to ensure that the 471 "self" link has all instance data that is needed for use. 473 A hyper-schema implementation MUST recognize that a link with 474 relation type "self" that has the entire current instance document as 475 its context describes how a user agent can interact with the resource 476 represented by that instance document. 478 6.2.3. "collection" and "item" Links 480 RFC 6573 [RFC6573] defines and registers the "item" and "collection" 481 link relation types. JSON Hyper-Schema imposes additional semantics 482 on collection resources indicated by these types. 484 Implementations MUST recognize the target of a "collection" link and 485 the context of an "item" link as collections. 487 A well-known design pattern in hypermedia is to use a collection 488 resource to create a member of the collection and give it a server- 489 assigned URI. If the protocol indicated by the URI scheme defines a 490 specific method that is suited to creating a resource with a server- 491 assigned URI, then a collection resource, as identified by these link 492 relation types, MUST NOT define semantics for that method that 493 conflict with the semantics of creating a collection member. 494 Collection resources MAY implement item creation via such a protocol 495 method, and user agents MAY assume that any such operation, if it 496 exists, has item creation semantics. 498 As such a method would correspond to JSON Hyper-Schema's data 499 submission concept, the "submissionSchema" (Section 6.6.4.2) field 500 for the link SHOULD be compatible with the schema of the 501 representation of the collection's items, as indicated by the "item" 502 link's target resource or the "self" link of the "collection" link's 503 context resource. 505 6.2.4. Using Extension Relation Types 507 When no registered relation (aside from "related") applies, users are 508 encouraged to mint their own extension relation types, as described 509 in section 2.1.2 of RFC 8288 [RFC8288]. The simplest approaches for 510 choosing link relation type URIs are to either use a URI scheme that 511 is already in use to identify the system's primary resources, or to 512 use a human-readable, non-dereferenceable URI scheme such as "tag", 513 defined by RFC 4151 [RFC4151]. 515 Extension relation type URIs need not be dereferenceable, even when 516 using a scheme that allows it. 518 6.3. Link Target 520 The target URI template is used to identify the link's target, 521 potentially making use of instance data. Additionally, with 522 "hrefSchema" (Section 6.6.1), this template can identify a set of 523 possible target resources to use based on client input. The full 524 process of resolving the URI template, with or without client input, 525 is covered in the URI Templating (Section 7.2) section. 527 6.3.1. href 529 The value of the "href" link description property is a template used 530 to determine the target URI of the related resource. The value of 531 the instance property MUST be resolved as a URI-reference [RFC3986] 532 against the base URI of the instance. 534 This property is REQUIRED. 536 6.4. Adjusting URI Template Resolution 538 The keywords in this section are used when resolving all URI 539 Templates involved in hyper-schema: "base", "anchor", and "href". 540 See the URI Templating (Section 7.2) section for the complete 541 template resolution algorithm. 543 Note that when resolving a "base" template, the attachment point from 544 which resolution begins is the attachment point of the "href" or 545 "anchor" keyword being resolved which requires "base" templates to be 546 resolved, not the attachment point of the "base" keyword itself. 548 6.4.1. templatePointers 550 The value of the "templatePointers" link description property MUST be 551 an object. Each property value in the object MUST be a valid JSON 552 Pointer [RFC6901], or a valid Relative JSON Pointer 553 [relative-json-pointer] which is evaluated relative to the attachment 554 point of the link for which the template is being resolved. 556 For each property name in the object that matches a variable name in 557 the template being resolved, the value of that property adjusts the 558 starting position of variable resolution for that variable. 559 Properties which do not match template variable names in the template 560 being resolved MUST be ignored. 562 6.4.2. templateRequired 564 The value of this keyword MUST be an array, and the elements MUST be 565 unique. Each element SHOULD match a variable in the link's URI 566 Template, without percent-encoding. After completing the entire URI 567 Template resolution process, if any variable that is present in this 568 array does not have a value, the link MUST NOT be used. 570 6.5. Link Target Attributes 572 All properties in this section are advisory only. While keywords 573 such as "title" and "description" are used primarily to present the 574 link to users, those keywords that predict the nature of a link 575 interaction or response MUST NOT be considered authoritative. The 576 runtime behavior of the target resource MUST be respected whenever it 577 conflicts with the target attributes in the LDO. 579 6.5.1. title 581 This property defines a title for the link. The value MUST be a 582 string. 584 User agents MAY use this title when presenting the link to the user. 586 6.5.2. description 588 This property provides additional information beyond what is present 589 in the title. The value MUST be a string. While a title is 590 preferably short, a description can be used to go into more detail 591 about the purpose and usage of the link. 593 User agents MAY use this description when presenting the link to the 594 user. 596 6.5.3. targetMediaType 598 The value of this property represents the media type RFC 2046 599 [RFC2046], that is expected to be returned when fetching this 600 resource. This property value MAY be a media range instead, using 601 the same pattern defined in RFC 7231, section 5.3.2 - HTTP "Accept" 602 header [RFC7231]. 604 This property is analogous to the "type" property of other link 605 serialization formats. User agents MAY use this information to 606 inform the interface they present to the user before the link is 607 followed, but MUST NOT use this information in the interpretation of 608 the resulting data. Instead, a user agent MUST use the media type 609 given by the response for run-time interpretation. See the section 610 on "Security Concerns" (Section 10) for a detailed examination of 611 mis-use of "targetMediaType". 613 For protocols supporting content-negotiation, implementations MAY 614 choose to describe possible target media types using protocol- 615 specific information in "headerSchema" (Section 6.6.2). If both 616 protocol-specific information and "targetMediaType" are present, then 617 the value of "targetMediaType" MUST be compatible with the protocol- 618 specific information, and SHOULD indicate the media type that will be 619 returned in the absence of content negotiation. 621 When no such protocol-specific information is available, or when the 622 implementation does not recognize the protocol involved, then the 623 value SHOULD be taken to be "application/json". 625 6.5.4. targetSchema 627 This property provides a schema that is expected to describe the link 628 target's representation. Depending on the protocol, the schema may 629 or may not describe the request or response to any particular 630 operation performed with the link. See the JSON Hyper-Schema and 631 HTTP (Section 8) section for an in-depth discussion of how this 632 keyword is used with HTTP. 634 6.5.5. targetHints 636 [[CREF1: This section attempts to strike a balance between 637 comprehensiveness and flexibility by deferring most of its structure 638 to the protocol indicated by the URI scheme. Note that a resource 639 can be identified by a URI with a dereferenceable scheme, yet not be 640 accessible over that protocol. While currently very loose, this 641 section is expected to become more well-defined based on draft 642 feedback, and may change significantly in future drafts. ]] 644 The value of this property is advisory only. It represents 645 information that is expected to be discoverable through interacting 646 with the target resource, typically in the form of protocol-specific 647 control information or meta-data such as headers returned in response 648 to an HTTP HEAD or OPTIONS request. The protocol is determined by 649 the "href" URI scheme, although note that resources are not 650 guaranteed to be accessible over such a protocol. 652 The value of this property SHOULD be an object. The keys to this 653 object SHOULD be lower-cased forms of the control data field names. 654 Each value SHOULD be an array, in order to uniformly handle multi- 655 valued fields. Multiple values MUST be presented as an array, and 656 not as a single string. 658 Protocols with control information not suitable for representation as 659 a JSON object MAY be represented by another data type, such as an 660 array. 662 Values that cannot be understood as part of the indicated protocol 663 MUST be ignored by a JSON Hyper-Schema implementation. Applications 664 MAY make use of such values, but MUST NOT assume interoperability 665 with other implementations. 667 Implementations MUST NOT assume that all discoverable information is 668 accounted for in this object. Client applications MUST properly 669 handle run-time responses that contradict this property's values. 671 Client applications MUST NOT assume that an implementation will 672 automatically take any action based on the value of this property. 674 See "JSON Hyper-Schema and HTTP" (Section 8) for guidance on using 675 this keyword with HTTP and analogous protocols. 677 6.6. Link Input 679 There are four ways to use client input with a link, and each is 680 addressed by a separate link description object keyword. When 681 performing operations, user agents SHOULD ignore schemas that are not 682 relevant to their semantics. 684 6.6.1. hrefSchema 686 The value of the "hrefSchema" link description property MUST be a 687 valid JSON Schema. This schema is used to validate user input or 688 other user agent data for filling out the URI Template in "href" 689 (Section 6.3.1). 691 Omitting "hrefSchema" or setting the entire schema to "false" 692 prevents any user agent data from being accepted. 694 Setting any subschema that applies to a particular variable to the 695 JSON literal value "false" prevents any user agent data from being 696 accepted for that single variable. 698 For template variables that can be resolved from the instance data, 699 if the instance data is valid against all applicable subschemas in 700 "hrefSchema", then it MUST be used to pre-populate the input data set 701 for that variable. 703 Note that even when data is pre-populated from the instance, the 704 validation schema for that variable in "hrefSchema" need not be 705 identical to the validation schema(s) that apply to the instance 706 data's location. This allows for different validation rules for user 707 agent data, such as supporting spelled-out months for date-time 708 input, but using the standard date-time format for storage. 710 After input is accepted, potentially overriding the pre-populated 711 instance data, the resulting data set MUST successfully validate 712 against the value of "hrefSchema". If it does not then the link MUST 713 NOT be used. If it is valid, then the process given in the "URI 714 Templating" section continues with this updated data set. 716 6.6.2. headerSchema 718 [[CREF2: As with "targetHints", this keyword is somewhat under- 719 specified to encourage experimentation and feedback as we try to 720 balance flexibility and clarity. ]] 722 If present, this property is a schema for protocol-specific request 723 headers or analogous control and meta-data. The value of this object 724 MUST be a valid JSON Schema. The protocol is determined by the 725 "href" URI scheme, although note that resources are not guaranteed to 726 be accessible over such a protocol. The schema is advisory only; the 727 target resource's behavior is not constrained by its presence. 729 The purpose of this keyword is to advertise target resource 730 interaction features, and indicate to user agents and client 731 applications what headers and header values are likely to be useful. 732 User agents and client applications MAY use the schema to validate 733 relevant headers, but MUST NOT assume that missing headers or values 734 are forbidden from use. While schema authors MAY set 735 "additionalProperties" to false, this is NOT RECOMMENDED and MUST NOT 736 prevent client applications or user agents from supplying additional 737 headers when requests are made. 739 The exact mapping of the JSON data model into the headers is 740 protocol-dependent. However, in most cases this schema SHOULD 741 specify a type of "object", and the property names SHOULD be lower- 742 cased forms of the control data field names. See the "JSON Hyper- 743 Schema and HTTP" (Section 8) section for detailed guidance on using 744 this keyword with HTTP and analogous protocols. 746 "headerSchema" is applicable to any request method or command that 747 the protocol supports. When generating a request, user agents and 748 client applications SHOULD ignore schemas for headers that are not 749 relevant to that request. 751 6.6.3. Manipulating the Target Resource Representation 753 In JSON Hyper-Schema, "targetSchema" (Section 6.5.4) supplies a non- 754 authoritative description of the target resource's representation. A 755 client application can use "targetSchema" to structure input for 756 replacing or modifying the representation, or as the base 757 representation for building a patch document based on a patch media 758 type. 760 Alternatively, if "targetSchema" is absent or if the client 761 application prefers to only use authoritative information, it can 762 interact with the target resource to confirm or discover its 763 representation structure. 765 "targetSchema" is not intended to describe link operation responses, 766 except when the response semantics indicate that it is a 767 representation of the target resource. In all cases, the schema 768 indicated by the response itself is authoritative. See "JSON Hyper- 769 Schema and HTTP" (Section 8) for detailed examples. 771 6.6.4. Submitting Data for Processing 773 The "submissionSchema" (Section 6.6.4.2) and "submissionMediaType" 774 (Section 6.6.4.1) keywords describe the domain of the processing 775 function implemented by the target resource. Otherwise, as noted 776 above, the submission schema and media type are ignored for 777 operations to which they are not relevant. 779 6.6.4.1. submissionMediaType 781 If present, this property indicates the media type format the client 782 application and user agent should use for the request payload 783 described by "submissionSchema" (Section 6.6.4.2). 785 Omitting this keyword has the same behavior as a value of 786 application/json. 788 Note that "submissionMediaType" and "submissionSchema" are not 789 restricted to HTTP URIs. [[CREF3: This statement might move to 790 wherever the example ends up.]] 792 6.6.4.2. submissionSchema 794 This property contains a schema which defines the acceptable 795 structure of the document to be encoded according to the 796 "submissionMediaType" property and sent to the target resource for 797 processing. This can be viewed as describing the domain of the 798 processing function implemented by the target resource. 800 This is a separate concept from the "targetSchema" (Section 6.5.4) 801 property, which describes the target information resource (including 802 for replacing the contents of the resource in a PUT request), unlike 803 "submissionSchema" which describes the user-submitted request data to 804 be evaluated by the resource. "submissionSchema" is intended for use 805 with requests that have payloads that are not necessarily defined in 806 terms of the target representation. 808 Omitting "submissionSchema" has the same behavior as a value of 809 "true". 811 7. Implementation Requirements 813 At a high level, a conforming implementation will meet the following 814 requirements. Each of these requirements is covered in more detail 815 in the individual keyword sections and keyword group overviews. 817 Note that the requirements around how an implementation MUST 818 recognize "self", "collection", and "item" links are thoroughly 819 covered in the link relation type (Section 6.2) section and are not 820 repeated here. 822 While it is not a mandatory format for implementations, the output 823 format used in the test suite summarizes what needs to be computed 824 for each link before it can be used: 826 contextUri The fully resolved URI (with scheme) of the context 827 resource. If the context is not the entire resource and there is 828 a usable fragment identifier syntax, then the URI includes a 829 fragment. Note that there is no such syntax for application/json. 831 contextPointer The JSON Pointer for the location within the instance 832 of the context resource. If the instance media type supports JSON 833 Pointers as fragment identifiers, this pointer will be the same as 834 the one encoded in the fragment of the "contextUri" field. 836 rel The link relation type, as it appears in the LDO. 838 targetUri The fully resolved URI (with a scheme) of the target 839 resource. If the link accepts input, this can only be produced 840 once the input has been supplied. 842 hrefInputTemplates The list of partially resolved URI references for 843 a link that accepts input. The first entry in the list is the 844 partially resolved "href". The additional entries, if any, are 845 the partially resolved "base" values ordered from the most 846 immediate out to the root of the schema. Template variables that 847 are pre-populated in the input are not resolved at this stage, as 848 the pre-populated value can be overridden. 850 hrefPrepopulatedInput The data set that the user agent should use to 851 prepopulate any input mechanism before accepting client input. If 852 input is to be accepted but no fields are to be pre-populated, 853 then this will be an empty object. 855 attachmentPointer The JSON Pointer for the location within the 856 instance to which the link is attached. By default, "contextUri" 857 and "attachmentUri" are the same, but "contextUri" can be changed 858 by LDO keywords, while "attachmentUri" cannot. 860 Other LDO keywords that are not involved in producing the above 861 information are included exactly as they appear when producing output 862 for the test suite. Those fields will not be further discussed here 863 unless specifically relevant. 865 7.1. Link Discovery and Look-Up 867 Before links can be used, they must be discovered by applying the 868 hyper-schema to the instance and finding all applicable and valid 869 links. Note that in addition to collecting valid links, any "base" 870 (Section 5.1) values necessary to resolve each LDO's URI Templates 871 must also be located and associated with the LDO through whatever 872 mechanism is most useful for the implementation's URI Template 873 resolution process. 875 And implementation MUST support looking up links by either their 876 attachment pointer or context pointer, either by performing the look- 877 up or by providing the set of all links with both pointers determined 878 so that user agents can implement the look-up themselves. 880 When performing look-ups by context pointer, links that are attached 881 to elements of the same array MUST be returned in the same order as 882 the array elements to which they are attached. 884 7.2. URI Templating 886 Three hyper-schema keywords are URI Templates [RFC6570]: "base", 887 "anchor", and "href". Each are resolved separately to URI- 888 references, and then the anchor or href URI-reference is resolved 889 against the base (which is itself resolved against earlier bases as 890 needed, each of which was first resolved from a URI Template to a 891 URI-reference). 893 All three keywords share the same algorithm for resolving variables 894 from instance data, which makes use of the "templatePointers" and 895 "templateRequired" keywords. When resolving "href", both it and any 896 "base" templates needed for resolution to an absolute URI, the 897 algorithm is modified to optionally accept user input based on the 898 "hrefSchema" keyword. 900 For each URI Template (T), the following pseudocode describes an 901 algorithm for resolving T into a URI-reference (R). For the purpose 902 of this algorithm: 904 o "ldo.templatePointers" is an empty object if the keyword was not 905 present and "ldo.templateRequired" is likewise an empty array. 907 o "attachmentPointer" is the absolute JSON Pointer for the 908 attachment location of the LDO. 910 o "getApplicableSchemas()" returns an iterable set of all 911 (sub)schemas that apply to the attachment point in the instance. 913 This algorithm should be applied first to either "href" or "anchor", 914 and then as needed to each successive "base". The order is 915 important, as it is not always possible to tell whether a template 916 will resolve to a full URI or a URI-reference. 918 In English, the high-level algorithm is: 920 1. Populate template variable data from the instance 922 2. If input is desired, accept input 924 3. Check that all required variables have a value 926 4. Encode values into strings and fill out the template 928 This is the high-level algorithm as pseudocode. "T" comes from 929 either "href" or "anchor" within the LDO, or from "base" in a 930 containing schema. Pseudocode for each step follows. 931 "initialTemplateKeyword" indicates which of the two started the 932 process (since "base" is always resolved in order to finish resolving 933 one or the other of those keywords). 935 templateData = populateDataFromInstance(T, ldo, instance) 937 if initialTemplateKeyword == "href" and ldo.hrefSchema exists: 938 inputData = acceptInput(ldo, instance, templateData) 939 for varname in inputData: 940 templateData[varname] = inputData[varname] 942 for varname in ldo.templateRequired: 943 if not exists templateData[varname] 944 fatal("Missing required variable(s)") 946 templateData = stringEncode(templateData) 947 R = rfc6570ResolutionAlgorithm(T, templateData) 949 7.2.1. Populating Template Data From the Instance 951 This step looks at various locations in the instance for variable 952 values. For each variable: 954 1. Use "templatePointers" to find a value if the variable appears in 955 that keyword's value 957 2. Otherwise, look for a property name matching the variable in the 958 instance location to which the link is attached 960 3. In either case, if there is a value at the location, put it in 961 the template resolution data set 963 for varname in T: 964 varname = rfc3986PercentDecode(varname) 965 if varname in ldo.templatePointers: 966 valuePointer = templatePointers[varname] 967 if valuePointer is relative: 968 valuePointer = resolveRelative(attachmentPointer, 969 valuePointer) 970 else 971 valuePointer = attachmentPointer + "/" + varname 973 value = instance.valueAt(valuePointer) 974 if value is defined: 975 templateData[varname] = value 977 7.2.2. Accepting Input for Template Data 979 This step is relatively complex, as there are several cases to 980 support. Some variables will forbid input and some will allow it. 981 Some will have initial values that need to be presented in the input 982 interface, and some will not. 984 1. Determine which variables can accept input 986 2. Pre-populate the input data set if the template resolution data 987 set has a value 989 3. Accept input (present a web form, make a callback, etc.) 991 4. Validate the input data set, (not the template resolution data 992 set) 994 5. Put the input in the template resolution data set, overriding any 995 existing values 997 "InputForm" represents whatever sort of input mechanism is 998 appropriate. This may be a literal web form, or may be a more 999 programmatic construct such as a callback function accepting specific 1000 fields and data types, with the given initial values, if any. 1002 form = new InputForm() 1003 for varname in T: 1004 useField = true 1005 useInitialData = true 1006 for schema in getApplicableSchemas(ldo.hrefSchema, 1007 "/" + varname): 1008 if schema is false: 1009 useField = false 1010 break 1012 if varname in templateData and 1013 not isValid(templateData[varname], schema)): 1014 useInitialData = false 1015 break 1017 if useField: 1018 if useInitialData: 1019 form.addInputFieldFor(varname, ldo.hrefSchema, 1020 templateData[varname]) 1021 else: 1022 form.addInputFieldFor(varname, ldo.hrefSchema) 1024 inputData = form.acceptInput() 1026 if not isValid(inputData, hrefSchema): 1027 fatal("Input invalid, link is not usable") 1029 return inputData: 1031 7.2.3. Encoding Data as Strings 1033 This section is straightforward, converting literals to their names 1034 as strings, and converting numbers to strings in the most obvious 1035 manner, and percent-encoding as needed for use in the URI. 1037 for varname in templateData: 1038 value = templateData[varname] 1039 if value is true: 1040 templateData[varname] = "true" 1041 else if value is false: 1042 temlateData[varname] = "false" 1043 else if value is null: 1044 templateData[varname] = "null" 1045 else if value is a number: 1046 templateData[varname] = 1047 bestEffortOriginalJsonString(value) 1048 else: 1049 templateData[varname] = rfc3986PercentEncode(value) 1051 In some software environments the original JSON representation of a 1052 number will not be available (there is no way to tell the difference 1053 between 1.0 and 1), so any reasonable representation should be used. 1054 Schema and API authors should bear this in mind, and use other types 1055 (such as string or boolean) if the exact representation is important. 1056 If the number was provide as input in the form of a string, the 1057 string used as input SHOULD be used. 1059 7.3. Providing Access to LDO Keywords 1061 For a given link, an implementation MUST make the values of all 1062 target attribute keywords directly available to the user agent. 1063 Implementations MAY provide additional interfaces for using this 1064 information, as discussed in each keyword's section. 1066 For a given link, an implementation MUST make the value of each input 1067 schema keyword directly available to the user agent. 1069 To encourage encapsulation of the URI Template resolution process, 1070 implementations MAY omit the LDO keywords that are used only to 1071 construct URIs. However, implementations MUST provide access to the 1072 link relation type. 1074 Unrecognized keywords SHOULD be made available to the user agent, and 1075 MUST otherwise be ignored. 1077 7.4. Requests 1079 A hyper-schema implementation SHOULD provide access to all 1080 information needed to construct any valid request to the target 1081 resource. 1083 The LDO can express all information needed to perform any operation 1084 on a link. This section explains what hyper-schema fields a user 1085 agent should examine to build requests from any combination of 1086 instance data and client input. A hyper-schema implementation is not 1087 itself expected to construct and send requests. 1089 Target URI construction rules, including "hrefSchema" for accepting 1090 input, are identical for all possible requests. 1092 Requests that do not carry a body payload do not require additional 1093 keyword support. 1095 Requests that take a target representation as a payload SHOULD use 1096 the "targetSchema" and "targetMediaType" keywords for input 1097 description and payload validation. If a protocol allows an 1098 operation taking a payload that is based on the representation as 1099 modified by a media type (such as a patch media type), then such a 1100 media type SHOULD be indicated through "targetHints" in a protocol- 1101 specific manner. 1103 Requests that take a payload that is not derived from the target 1104 resource's representation SHOULD use the "submissionSchema" and 1105 "submissionMediaType" keywords for input description and payload 1106 validation. Protocols used in hypermedia generally only support one 1107 such non-representation operation per link. 1109 RPC systems that pipe many application operations with arbitrarily 1110 different request structures through a single hypermedia protocol 1111 operation are outside of the scope of a hypermedia format such as 1112 JSON Hyper-Schema. 1114 7.5. Responses 1116 As a hypermedia format, JSON Hyper-Schema is concerned with 1117 describing a resource, including describing its links in sufficient 1118 detail to make all valid requests. It is not concerned with directly 1119 describing all possible responses for those requests. 1121 As in any hypermedia system, responses are expected to be self- 1122 describing. In the context of hyper-schema, this means that each 1123 response MUST link its own hyper-schema(s). While responses that 1124 consist of a representation of the target resource are expected to be 1125 valid against "targetSchema" and "targetMediaType", those keywords 1126 are advisory only and MUST be ignored if contradicted by the response 1127 itself. 1129 Other responses, including error responses, complex redirections, and 1130 processing status representations SHOULD also link to their own 1131 schemas and use appropriate media types (e.g. "application/ 1132 problem+json" [RFC7807] for errors). Certain errors might not link a 1133 schema due to being generated by an intermediary that is not aware of 1134 hyper-schema, rather than by the origin. 1136 User agents are expected to understand protocol status codes and 1137 response media types well enough to handle common situations, and 1138 provide enough information to client applications to handle domain- 1139 specific responses. 1141 Statically mapping all possible responses and their schemas at design 1142 time is outside of the scope of JSON Hyper-Schema, but may be within 1143 the scope of other JSON Schema vocabularies which build on hyper- 1144 schema (see Appendix A.3). 1146 7.6. Streaming Parsers 1148 The requirements around discovering links based on their context, or 1149 using the context of links to identify collections, present unique 1150 challenges when used with streaming parsers. It is not possible to 1151 authoritatively fulfill these requirements without processing the 1152 entire schema and instance documents. 1154 Such implementations MAY choose to return non-authoritative answers 1155 based on data processed to date. When offering this approach, 1156 implementations MUST be clear on the nature of the response, and MUST 1157 offer an option to block and wait until all data is processed and an 1158 authoritative answer can be returned. 1160 8. JSON Hyper-Schema and HTTP 1162 While JSON Hyper-Schema is a hypermedia format and therefore 1163 protocol-independent, it is expected that its most common use will be 1164 in HTTP systems, or systems using protocols such as CoAP that are 1165 explicitly analogous to HTTP. 1167 This section provides guidance on how to use each common HTTP method 1168 with a link, and how collection resources impose additional 1169 constraints on HTTP POST. Additionally, guidance is provided on 1170 hinting at HTTP response header values and describing possible HTTP 1171 request headers that are relevant to the given resource. 1173 Section 11 of the JSON Schema core specification [json-schema] 1174 provides guidance on linking instances in a hypermedia system to 1175 their schemas. This may be done with network-accessible schemas, or 1176 may simply identify schemas which were pre-packaged within the client 1177 application. JSON Hyper-Schema intentionally does not constrain this 1178 mechanism, although it is RECOMMENDED that the techniques outlined in 1179 the core specification be used to whatever extent is possible. 1181 8.1. One Link Per Target and Relation Type 1183 Link Description Objects do not directly indicate what operations, 1184 such as HTTP methods, are supported by the target resource. Instead, 1185 operations should be inferred primarily from link relation types 1186 (Section 6.2.1) and URI schemes. 1188 This means that for each target resource and link relation type pair, 1189 schema authors SHOULD only define a single LDO. While it is possible 1190 to use "allow" with "targetHints" to repeat a relation type and 1191 target pair with different HTTP methods marked as allowed, this is 1192 NOT RECOMMENDED and may not be well-supported by conforming 1193 implementations. 1195 All information necessary to use each HTTP method can be conveyed in 1196 a single LDO as explained in this section. The "allow" field in 1197 "targetHints" is intended simply to hint at which operations are 1198 supported, not to separately define each operation. 1200 Note, however, that a resource may always decline an operation at 1201 runtime, for instance due to authorization failure, or due to other 1202 application state that controls the operation's availability. 1204 8.2. "targetSchema" and HTTP 1206 "targetSchema" describes the resource on the target end of the link, 1207 while "targetMediaType" defines that resource's media type. With 1208 HTTP links, "headerSchema" can also be used to describe valid values 1209 for use in an "Accept" request header, which can support multiple 1210 media types or media ranges. When both ways of indicating the target 1211 media type are present, "targetMediaType" SHOULD indicate the default 1212 representation media type, while the schema for "accept" in 1213 "headerSchema" SHOULD include the default as well as any alternate 1214 media types or media ranges that can be requested. 1216 Since the semantics of many HTTP methods are defined in terms of the 1217 target resource, "targetSchema" is used for requests and/or responses 1218 for several HTTP methods. In particular, "targetSchema" suggests 1219 what a client application can expect for the response to an HTTP GET 1220 or any response for which the "Content-Location" header is equal to 1221 the request URI, and what a client application should send if it 1222 replaces the resource in an HTTP PUT request. These correlations are 1223 defined by RFC 7231, section 4.3.1 - "GET", section 4.3.4 "PUT", and 1224 section 3.1.4.2, "Content-Location" [RFC7231]. 1226 Per RFC 5789 [RFC5789], the request structure for an HTTP PATCH is 1227 determined by the combination of "targetSchema" and the request media 1228 type, which is conveyed by the "Accept-Patch" header, which may be 1229 included in "targetHints". Media types that are suitable for PATCH- 1230 ing define a syntax for expressing changes to a document, which can 1231 be applied to the representation described by "targetSchema" to 1232 determine the set of syntactically valid request payloads. Often, 1233 the simplest way to validate a PATCH request is to apply it and 1234 validate the result as a normal representation. 1236 8.3. HTTP POST and the "submission*" keywords 1238 JSON Hyper-Schema allows for resources that process arbitrary data in 1239 addition to or instead of working with the target's representation. 1240 This arbitrary data is described by the "submissionSchema" and 1241 "submissionMediaType" keywords. In the case of HTTP, the POST method 1242 is the only one that handles such data. While there are certain 1243 conventions around using POST with collections, the semantics of a 1244 POST request are defined by the target resource, not HTTP. 1246 In addition to the protocol-neutral "submission*" keywords (see 1247 Section 9.3 for a non-HTTP example), the "Accept-Post" header can be 1248 used to specify the necessary media type, and MAY be advertised via 1249 the "targetHints" field. [[CREF4: What happens if both are used? 1250 Also, "submissionSchema" is a MUST to support, while "targetHints" 1251 are at most a SHOULD. But forbidding the use of "Accept-Post" in 1252 "targetHints" seems incorrect. ]] 1254 Successful responses to POST other than a 201 or a 200 with "Content- 1255 Location" set likewise have no HTTP-defined semantics. As with all 1256 HTTP responses, any representation in the response should link to its 1257 own hyper-schema to indicate how it may be processed. As noted in 1258 Appendix A.2, connecting hyperlinks with all possible operation 1259 responses is not within the scope of JSON Hyper-Schema. 1261 8.4. Optimizing HTTP Discoverability With "targetHints" 1263 [[CREF5: It would be good to also include a section with CoAP 1264 examples.]] 1266 JSON serializations of HTTP response header information SHOULD follow 1267 the guidelines established by the work in progress "A JSON Encoding 1268 for HTTP Header Field Values" [I-D.reschke-http-jfv]. Approaches 1269 shown in that document's examples SHOULD be applied to other 1270 similarly structured headers wherever possible. 1272 Headers for all possible HTTP method responses all share 1273 "headerSchema". In particular, both headers that appear in a HEAD 1274 response and those that appear in an OPTIONS response can appear. No 1275 distinction is made within "headerSchema" as to which method response 1276 contains which header. 1278 It is RECOMMENDED that schema authors provide hints for the values of 1279 the following types of HTTP headers whenever applicable: 1281 o Method allowance 1283 o Method-specific request media types 1285 o Authentication challenges 1287 In general, headers that are likely to have different values at 1288 different times SHOULD NOT be included in "targetHints". 1290 8.5. Advertising HTTP Features With "headerSchema" 1292 Schemas SHOULD be written to describe JSON serializations that follow 1293 guidelines established by the work in progress "A JSON Encoding for 1294 HTTP Header Field Values" [I-D.reschke-http-jfv] Approaches shown in 1295 that document's examples SHOULD be applied to other similarly 1296 structured headers wherever possible. 1298 It is RECOMMENDED that schema authors describe the available usage of 1299 the following types of HTTP headers whenever applicable: 1301 o Content negotiation 1303 o Authentication and authorization 1305 o Range requests 1307 o The "Prefer" header 1309 Headers such as cache control and conditional request headers are 1310 generally implemented by intermediaries rather than the resource, and 1311 are therefore not generally useful to describe. While the resource 1312 must supply the information needed to use conditional requests, the 1313 runtime handling of such headers and related responses is not 1314 resource-specific. 1316 8.6. Creating Resources Through Collections 1318 When using HTTP, or a protocol such as CoAP that is explicitly 1319 analogous to HTTP, this is done by POST-ing a representation of the 1320 individual resource to be created to the collection resource. The 1321 process for recognizing collection and item resources is described in 1322 Section 6.2.3. 1324 8.7. Content Negotiation and Schema Evolution 1326 JSON Hyper-Schema facilitates HTTP content negotiation, and allows 1327 for a hybrid of the proactive and reactive strategies. As mentioned 1328 above, a hyper-schema can include a schema for HTTP headers such as 1329 "Accept", "Accept-Charset", "Accept-Language", etc with the 1330 "headerSchema" keyword. A user agent or client application can use 1331 information in this schema, such as an enumerated list of supported 1332 languages, in lieu of making an initial request to start the reactive 1333 negotiation process. 1335 In this way, the proactive content negotiation technique of setting 1336 these headers can be informed by server information about what values 1337 are possible, similar to examining a list of alternatives in reactive 1338 negotiation. 1340 For media types that allow specifying a schema as a media type 1341 parameter, the "Accept" values sent in a request or advertised in 1342 "headerSchema" can include the URI(s) of the schema(s) to which the 1343 negotiated representation is expected to conform. One possible use 1344 for schema parameters in content negotiation is if the resource has 1345 conformed to several different schema versions over time. The client 1346 application can indicate what version(s) it understands in the 1347 "Accept" header in this way. 1349 9. Examples 1351 This section shows how the keywords that construct URIs and JSON 1352 Pointers are used. The results are shown in the format used by the 1353 test suite. [[CREF6: Need to post that and link it, but it should be 1354 pretty self-explanatory to those of you reviewing things at this 1355 stage. ]] 1357 Most other keywords are either straightforward ("title" and 1358 "description"), apply validation to specific sorts of input, 1359 requests, or responses, or have protocol-specific behavior. Examples 1360 demonstrating HTTP usage are available in an Appendix (Section 8). 1362 9.1. Entry Point Links, No Templates 1364 For this example, we will assume an example API with a documented 1365 entry point URI of https://example.com, which is an empty JSON object 1366 with a link to a schema. Here, the entry point has no data of its 1367 own and exists only to provide an initial set of links: 1369 GET https://api.example.com HTTP/1.1 1371 200 OK 1372 Content-Type: application/json 1373 Link: rel=describedBy 1374 {} 1376 The linked hyper-schema defines the API's base URI and provides two 1377 links: an "about" link to API documentation, and a "self" link 1378 indicating that this is a schema for the base URI. In this case the 1379 base URI is also the entry point URI. 1381 { 1382 "$id": "https://schema.example.com/entry", 1383 "$schema": "http://json-schema.org/draft-07/hyper-schema#", 1384 "base": "https://api.example.com/", 1385 "links": [ 1386 { 1387 "rel": "self", 1388 "href": "" 1389 }, { 1390 "rel": "about", 1391 "href": "/docs" 1392 } 1393 ] 1394 } 1396 These are the simplest possible links, with only a relation type and 1397 an "href" with no template variables. They resolve as follows: 1399 [ 1400 { 1401 "contextUri": "https://api.example.com", 1402 "contextPointer": "", 1403 "rel": "self", 1404 "targetUri": "https://api.example.com", 1405 "attachmentPointer": "" 1406 }, 1407 { 1408 "contextUri": "https://api.example.com", 1409 "contextPointer": "", 1410 "rel": "about", 1411 "targetUri": "https://api.example.com/docs", 1412 "attachmentPointer": "" 1413 } 1414 ] 1415 The attachment pointer is the root pointer (the only possibility with 1416 an empty object for the instance). The context URI is the default, 1417 which is the requested document. Since application/json does not 1418 allow for fragments, the context pointer is necessary to fully 1419 describe the context. Its default behavior is to be the same as the 1420 attachment pointer. 1422 9.2. Individually Identified Resources 1424 Let's add "things" to our system, starting with an individual thing: 1426 { 1427 "$id": "https://schema.example.com/thing", 1428 "$schema": "http://json-schema.org/draft-07/hyper-schema#", 1429 "base": "https://api.example.com/", 1430 "type": "object", 1431 "required": ["data"], 1432 "properties": { 1433 "id": {"$ref": "#/definitions/id"}, 1434 "data": true 1435 }, 1436 "links": [ 1437 { 1438 "rel": "self", 1439 "href": "things/{id}", 1440 "templateRequired": ["id"], 1441 "targetSchema": {"$ref": "#"} 1442 } 1443 ], 1444 "definitions": { 1445 "id": { 1446 "type": "integer", 1447 "minimum": 1, 1448 "readOnly": true 1449 } 1450 } 1451 } 1453 Our "thing" has a server-assigned id, which is required in order to 1454 construct the "self" link. It also has a "data" field which can be 1455 of any type. The reason for the "definitions" section will be clear 1456 in the next example. 1458 Note that "id" is not required by the validation schema, but is 1459 required by the self link. This makes sense: a "thing" only has a 1460 URI if it has been created, and the server has assigned an id. 1461 However, you can use this schema with an instance containing only the 1462 data field, which allows you to validate "thing" instances that you 1463 are about to create. 1465 Let's add a link to our entry point schema that lets you jump 1466 directly to a particular thing if you can supply it's id as input. 1467 To save space, only the new LDO is shown. Unlike "self" and "about", 1468 there is no IANA-registered relationship about hypothetical things, 1469 so an extension relationship is defined using the "tag:" URI scheme 1470 [RFC4151]: 1472 { 1473 "rel": "tag:rel.example.com,2017:thing", 1474 "href": "things/{id}", 1475 "hrefSchema": { 1476 "required": ["id"], 1477 "properties": { 1478 "id": {"$ref": "thing#/definitions/id"} 1479 } 1480 }, 1481 "targetSchema": {"$ref": "thing#"} 1482 } 1484 The "href" value here is the same, but everything else is different. 1485 Recall that the instance is an empty object, so "id" cannot be 1486 resolved from instance data. Instead it is required as client input. 1487 This LDO could also have used "templateRequired" but with "required" 1488 in "hrefSchema" it is not strictly necessary. Providing 1489 "templateRequired" without marking "id" as required in "hrefSchema" 1490 would lead to errors, as client input is the only possible source for 1491 resolving this link. 1493 9.3. Submitting a Payload and Accepting URI Input 1495 This example covers using the "submission" fields for non- 1496 representation input, as well as using them alongside of resolving 1497 the URI Template with input. Unlike HTML forms, which require either 1498 constructing a URI or sending a payload, but do not allow not both at 1499 once, JSON Hyper-Schema can describe both sorts of input for the same 1500 operation on the same link. 1502 The "submissionSchema" and "submissionMediaType" fields are for 1503 describing payloads that are not representations of the target 1504 resource. When used with "http(s)://" URIs, they generally refer to 1505 a POST request payload, as seen in the appendix on HTTP usage 1506 (Section 8). 1508 In this case, we use a "mailto:" URI, which, per RFC 6068, Section 3" 1509 [RFC6068], does not provide any operation for retrieving a resource. 1511 It can only be used to construct a message for sending. Since there 1512 is no concept of a retrievable, replaceable, or deletable target 1513 resource, "targetSchema" and "targetMediaType" are not used. Non- 1514 representation payloads are described by "submissionSchema" and 1515 "submissionMediaType". 1517 We use "submissionMediaType" to indicate a multipart/alternative 1518 payload format, providing two representations of the same data (HTML 1519 and plain text). Since a multipart/alternative message is an ordered 1520 sequence (the last part is the most preferred alternative), we model 1521 the sequence as an array in "submissionSchema". Since each part is 1522 itself a document with a media type, we model each item in the array 1523 as a string, using "contentMediaType" to indicate the format within 1524 the string. 1526 Note that media types such as multipart/form-data, which associate a 1527 name with each part and are not ordered, should be modeled as JSON 1528 objects rather than arrays. 1530 Note that some lines are wrapped to fit this document's width 1531 restrictions. 1533 { 1534 "$id": "https://schema.example.com/interesting-stuff", 1535 "$schema": "http://json-schema.org/draft-07/hyper-schema#", 1536 "required": ["stuffWorthEmailingAbout", "email", "title"], 1537 "properties": { 1538 "title": { 1539 "type": "string" 1540 }, 1541 "stuffWorthEmailingAbout": { 1542 "type": "string" 1543 }, 1544 "email": { 1545 "type": "string", 1546 "format": "email" 1547 }, 1548 "cc": false 1549 }, 1550 "links": [ 1551 { 1552 "rel": "author", 1553 "href": "mailto:{email}?subject={title}{&cc}", 1554 "templateRequired": ["email"], 1555 "hrefSchema": { 1556 "required": ["title"], 1557 "properties": { 1558 "title": { 1559 "type": "string" 1560 }, 1561 "cc": { 1562 "type": "string", 1563 "format": "email" 1564 }, 1565 "email": false 1566 } 1567 }, 1568 "submissionMediaType": 1569 "multipart/alternative; boundary=ab2", 1570 "submissionSchema": { 1571 "type": "array", 1572 "items": [ 1573 { 1574 "type": "string", 1575 "contentMediaType": 1576 "text/plain; charset=utf8" 1577 }, 1578 { 1579 "type": "string", 1580 "contentMediaType": "text/html" 1581 } 1582 ], 1583 "minItems": 2 1584 } 1585 } 1586 ] 1587 } 1589 For the URI parameters, each of the three demonstrates a different 1590 way of resolving the input: 1592 email: This variable's presence in "templateRequired" means that it 1593 must be resolved for the template to be used. Since the "false" 1594 schema assigned to it in "hrefSchema" excludes it from the input 1595 data set, it must be resolved from the instance. 1597 title: The instance field matching this variable is required, and it 1598 is also allowed in the input data. So its instance value is used 1599 to pre-populate the input data set before accepting client input. 1600 The client application can opt to leave the instance value in 1601 place. Since this field is required in "hrefSchema", the client 1602 application cannot delete it (although it could set it to an empty 1603 string). 1605 cc: The "false" schema set for this in the main schema prevents this 1606 field from having an instance value. If it is present at all, it 1607 must come from client input. As it is not required in 1608 "hrefSchema", it may not be used at all. 1610 So, given the following instance retrieved from 1611 "https://api.example.com/stuff": 1613 { 1614 "title": "The Awesome Thing", 1615 "stuffWorthEmailingAbout": "Lots of text here...", 1616 "email": "someone@exapmle.com" 1617 } 1619 We can partially resolve the link as follows, before asking the 1620 client application for input. 1622 { 1623 "contextUri": "https://api.example.com/stuff", 1624 "contextPointer": "", 1625 "rel": "author", 1626 "hrefInputTemplates": [ 1627 "mailto:someone@example.com?subject={title}{&cc}" 1628 ], 1629 "hrefPrepopulatedInput": { 1630 "title": "The Really Awesome Thing" 1631 }, 1632 "attachmentPointer": "" 1633 } 1635 Notice the "href*" keywords in place of "targetUri". These are three 1636 possible kinds of "targetUri" values covering different sorts of 1637 input. Here are examples of each: 1639 No additional or changed input: "mailto:someone@example.com?subject= 1640 The%20Awesome%20Thing" 1642 Change "title" to "your work": "mailto:someone@example.com?subject=y 1643 our%20work" 1645 Change title and add a "cc" of "other@elsewhere.org": 1646 "mailto:someone@example.com?subject=your%20work&cc=other@elsewhere 1647 .org" 1649 9.4. "anchor", "base" and URI Template Resolution 1651 A link is a typed connection from a context resource to a target 1652 resource. Older link serializations support a "rev" keyword that 1653 takes a link relation type as "rel" does, but reverses the semantics. 1654 This has long been deprecated, so JSON Hyper-Schema does not support 1655 it. Instead, "anchor"'s ability to change the context URI can be 1656 used to reverse the direction of a link. It can also be used to 1657 describe a link between two resources, neither of which is the 1658 current resource. 1660 As an example, there is an IANA-registered "up" relation, but there 1661 is no "down". In an HTTP Link header, you could implement "down" as 1662 ""rev": "up"". 1664 First let's look at how this could be done in HTTP, showing a "self" 1665 link and two semantically identical links, one with "rev": "up" and 1666 the other using "anchor" with "rel": "up" (line wrapped due to 1667 formatting limitations). 1669 GET https://api.example.com/trees/1/nodes/123 HTTP/1.1 1671 200 OK 1672 Content-Type: application/json 1673 Link: rel=self 1674 Link: rel=up 1675 anchor= 1676 Link: rev=up 1677 { 1678 "id": 123, 1679 "treeId": 1, 1680 "childIds": [456] 1681 } 1683 Note that the "rel=up" link has a target URI identical to the 1684 "rel=self" link, and sets "anchor" (which identifies the link's 1685 context) to the child's URI. This sort of reversed link is easily 1686 detectable by tools when a "self" link is also present. 1688 The following hyper-schema, applied to the instance in the response 1689 above, would produce the same "self" link and "up" link with 1690 "anchor". It also shows the use of a templated "base" URI, plus both 1691 absolute and relative JSON Pointers in "templatePointers". 1693 { 1694 "$id": "https://schema.example.com/tree-node", 1695 "$schema": "http://json-schema.org/draft-07/hyper-schema#", 1696 "base": "trees/{treeId}/", 1697 "properties": { 1698 "id": {"type": "integer"}, 1699 "treeId": {"type": "integer"}, 1700 "childIds": { 1701 "type": "array", 1702 "items": { 1703 "type": "integer", 1704 "links": [ 1705 { 1706 "anchor": "nodes/{thisNodeId}", 1707 "rel": "up", 1708 "href": "nodes/{childId}", 1709 "templatePointers": { 1710 "thisNodeId": "/id", 1711 "childId": "0" 1712 } 1713 } 1714 ] 1715 } 1716 } 1717 }, 1718 "links": [ 1719 { 1720 "rel": "self", 1721 "href": "nodes/{id}" 1722 } 1723 ] 1724 } 1726 The "base" template is evaluated identically for both the target 1727 ("href") and context ("anchor") URIs. 1729 Note the two different sorts of templatePointers used. "thisNodeId" 1730 is mapped to an absolute JSON Pointer, "/id", while "childId" is 1731 mapped to a relative pointer, "0", which indicates the value of the 1732 current item. Absolute JSON Pointers do not support any kind of 1733 wildcarding, so there is no way to specify a concept like "current 1734 item" without a relative JSON Pointer. 1736 9.5. Collections 1738 In many systems, individual resources are grouped into collections. 1739 Those collections also often provide a way to create individual item 1740 resources with server-assigned identifiers. 1742 For this example, we will re-use the individual thing schema as shown 1743 in an earlier section. It is repeated here for convenience, with an 1744 added "collection" link with a "targetSchema" reference pointing to 1745 the collection schema we will introduce next. 1747 { 1748 "$id": "https://schema.example.com/thing", 1749 "$schema": "http://json-schema.org/draft-07/hyper-schema#", 1750 "base": "https://api.example.com/", 1751 "type": "object", 1752 "required": ["data"], 1753 "properties": { 1754 "id": {"$ref": "#/definitions/id"}, 1755 "data": true 1756 }, 1757 "links": [ 1758 { 1759 "rel": "self", 1760 "href": "things/{id}", 1761 "templateRequired": ["id"], 1762 "targetSchema": {"$ref": "#"} 1763 }, { 1764 "rel": "collection", 1765 "href": "/things", 1766 "targetSchema": {"$ref": "thing-collection#"}, 1767 "submissionSchema": {"$ref": "#"} 1768 } 1769 ], 1770 "definitions": { 1771 "id": { 1772 "type": "integer", 1773 "minimum": 1, 1774 "readOnly": true 1775 } 1776 } 1777 } 1779 The "collection" link is the same for all items, so there are no URI 1780 Template variables. The "submissionSchema" is that of the item 1781 itself. As described in Section 6.2.3, if a "collection" link 1782 supports a submission mechanism (POST in HTTP) then it MUST implement 1783 item creation semantics. Therefore "submissionSchema" is the schema 1784 for creating a "thing" via this link. 1786 Now we want to describe collections of "thing"s. This schema 1787 describes a collection where each item representation is identical to 1788 the individual "thing" representation. While many collection 1789 representations only include subset of the item representations, this 1790 example uses the entirety to minimize the number of schemas involved. 1791 The actual collection items appear as an array within an object, as 1792 we will add more fields to the object in the next example. 1794 { 1795 "$id": "https://schema.example.com/thing-collection", 1796 "$schema": "http://json-schema.org/draft-07/hyper-schema#", 1797 "base": "https://api.example.com/", 1798 "type": "object", 1799 "required": ["elements"], 1800 "properties": { 1801 "elements": { 1802 "type": "array", 1803 "items": { 1804 "allOf": [{"$ref": "thing#"}], 1805 "links": [ 1806 { 1807 "anchorPointer": "", 1808 "rel": "item", 1809 "href": "things/{id}", 1810 "templateRequired": ["id"], 1811 "targetSchema": {"$ref": "thing#"} 1812 } 1813 ] 1814 } 1815 } 1816 }, 1817 "links": [ 1818 { 1819 "rel": "self", 1820 "href": "things", 1821 "targetSchema": {"$ref": "#"}, 1822 "submissionSchema": {"$ref": "thing"} 1823 } 1824 ] 1825 } 1826 Here is a simple two-element collection instance: 1828 { 1829 "elements": [ 1830 {"id": 12345, "data": {}}, 1831 {"id": 67890, "data": {}} 1832 ] 1833 } 1835 Here are all of the links that apply to this instance, including 1836 those that are defined in the referenced individual "thing" schema: 1838 [ 1839 { 1840 "contextUri": "https://api.example.com/things", 1841 "contextPointer": "", 1842 "rel": "self", 1843 "targetUri": "https://api.example.com/things", 1844 "attachmentPointer": "" 1845 }, 1846 { 1847 "contextUri": "https://api.example.com/things", 1848 "contextPointer": "/elements/0", 1849 "rel": "self", 1850 "targetUri": "https://api.example.com/things/12345", 1851 "attachmentPointer": "/elements/0" 1852 }, 1853 { 1854 "contextUri": "https://api.example.com/things", 1855 "contextPointer": "/elements/1", 1856 "rel": "self", 1857 "targetUri": "https://api.example.com/things/67890", 1858 "attachmentPointer": "/elements/1" 1859 }, 1860 { 1861 "contextUri": "https://api.example.com/things", 1862 "contextPointer": "", 1863 "rel": "item", 1864 "targetUri": "https://api.example.com/things/12345", 1865 "attachmentPointer": "/elements/0" 1866 }, 1867 { 1868 "contextUri": "https://api.example.com/things", 1869 "contextPointer": "", 1870 "rel": "item", 1871 "targetUri": "https://api.example.com/things/67890", 1872 "attachmentPointer": "/elements/1" 1873 }, 1874 { 1875 "contextUri": "https://api.example.com/things", 1876 "contextPointer": "/elements/0", 1877 "rel": "collection", 1878 "targetUri": "https://api.example.com/things", 1879 "attachmentPointer": "/elements/0" 1880 }, 1881 { 1882 "contextUri": "https://api.example.com/things", 1883 "contextPointer": "/elements/1", 1884 "rel": "collection", 1885 "targetUri": "https://api.example.com/things", 1886 "attachmentPointer": "/elements/1" 1887 } 1888 ] 1890 In all cases, the context URI is shown for an instance of media type 1891 application/json, which does not support fragments. If the instance 1892 media type was application/instance+json, which supports JSON Pointer 1893 fragments, then the context URIs would contain fragments identical to 1894 the context pointer field. For application/json and other media 1895 types without fragments, it is critically important to consider the 1896 context pointer as well as the context URI. 1898 There are three "self" links, one for the collection, and one for 1899 each item in the "elements" array. The item "self" links are defined 1900 in the individual "thing" schema which is referenced with "$ref". 1901 The three links can be distinguished by their context or attachment 1902 pointers. We will revisit the "submissionSchema" of the collection's 1903 "self" link in Section 9.5.2. 1905 There are two "item" links, one for each item in the "elements" 1906 array. Unlike the "self" links, these are defined only in the 1907 collection schema. Each of them have the same target URI as the 1908 corresponding "self" link that shares the same attachment pointer. 1909 However, each has a different context pointer. The context of the 1910 "self" link is the entry in "elements", while the context of the 1911 "item" link is always the entire collection regardless of the 1912 specific item. 1914 Finally, there are two "collection" links, one for each item in 1915 "elements". In the individual item schema, these produce links with 1916 the item resource as the context. When referenced from the 1917 collection schema, the context is the location in the "elements" 1918 array of the relevant "thing", rather than that "thing"'s own 1919 separate resource URI. 1921 The collection links have identical target URIs as there is only one 1922 relevant collection URI. While calculating both links as part of a 1923 full set of constructed links may not seem useful, when constructing 1924 links on an as-needed basis, this arrangement means that there is a 1925 "collection" link definition close at hand no matter which "elements" 1926 entry you are processing. 1928 9.5.1. Pagination 1930 Here we add pagination to our collection. There is a "meta" section 1931 to hold the information about current, next, and previous pages. 1932 Most of the schema is the same as in the previous section and has 1933 been omitted. Only new fields and new or (in the case of the main 1934 "self" link) changed links are shown in full. 1936 { 1937 "properties": { 1938 "elements": { 1939 ... 1940 }, 1941 "meta": { 1942 "type": "object", 1943 "properties": { 1944 "prev": {"$ref": "#/definitions/pagination"}, 1945 "current": {"$ref": "#/definitions/pagination"}, 1946 "next": {"$ref": "#/definitions/pagination"} 1947 } 1948 } 1949 }, 1950 "links": [ 1951 { 1952 "rel": "self", 1953 "href": "things{?offset,limit}", 1954 "templateRequired": ["offset", "limit"], 1955 "templatePointers": { 1956 "offset": "/meta/current/offset", 1957 "limit": "/meta/current/limit" 1958 }, 1959 "targetSchema": {"$ref": "#"} 1960 }, { 1961 "rel": "prev", 1962 "href": "things{?offset,limit}", 1963 "templateRequired": ["offset", "limit"], 1964 "templatePointers": { 1965 "offset": "/meta/prev/offset", 1966 "limit": "/meta/prev/limit" 1967 }, 1968 "targetSchema": {"$ref": "#"} 1970 }, { 1971 "rel": "next", 1972 "href": "things{?offset,limit}", 1973 "templateRequired": ["offset", "limit"], 1974 "templatePointers": { 1975 "offset": "/meta/next/offset", 1976 "limit": "/meta/next/limit" 1977 }, 1978 "targetSchema": {"$ref": "#"} 1979 } 1980 ], 1981 "definitions": { 1982 "pagination": { 1983 "type": "object", 1984 "properties": { 1985 "offset": { 1986 "type": "integer", 1987 "minimum": 0, 1988 "default": 0 1989 }, 1990 "limit": { 1991 "type": "integer", 1992 "minimum": 1, 1993 "maximum": 100, 1994 "default": 10 1995 } 1996 } 1997 } 1998 } 1999 } 2001 Notice that the "self" link includes the pagination query that 2002 produced the exact representation, rather than being a generic link 2003 to the collection allowing selecting the page via input. 2005 Given this instance: 2007 { 2008 "elements": [ 2009 {"id": 12345, "data": {}}, 2010 {"id": 67890, "data": {}} 2011 ], 2012 "meta": { 2013 "current": { 2014 "offset": 0, 2015 "limit": 2 2016 }, 2017 "next": { 2018 "offset": 3, 2019 "limit": 2 2020 } 2021 } 2022 } 2024 Here are all of the links that apply to this instance that either did 2025 not appear in the previous example or have been changed with 2026 pagination added. 2028 [ 2029 { 2030 "contextUri": "https://api.example.com/things", 2031 "contextPointer": "", 2032 "rel": "self", 2033 "targetUri": 2034 "https://api.example.com/things?offset=20,limit=2", 2035 "attachmentPointer": "" 2036 }, 2037 { 2038 "contextUri": "https://api.example.com/things", 2039 "contextPointer": "", 2040 "rel": "next", 2041 "targetUri": 2042 "https://api.example.com/things?offset=22,limit=2", 2043 "attachmentPointer": "" 2044 } 2045 ] 2047 Note that there is no "prev" link in the output, as we are looking at 2048 the first page. The lack of a "prev" field under "meta", together 2049 with the "prev" link's "templateRequired" values, means that the link 2050 is not usable with this particular instance. 2052 [[CREF7: It's not clear how pagination should work with the link from 2053 the "collection" links in the individual "thing" schema. 2054 Technically, a link from an item to a paginated or filtered 2055 collection should go to a page/filter that contains the item (in this 2056 case the "thing") that is the link context. See GitHub issue #421 2057 for more discussion. ]] 2059 Let's add a link for this collection to the entry point schema 2060 (Section 9.1), including pagination input in order to allow client 2061 applications to jump directly to a specific page. Recall that the 2062 entry point schema consists only of links, therefore we only show the 2063 newly added link: 2065 { 2066 "rel": "tag:rel.example.com,2017:thing-collection", 2067 "href": "/things{?offset,limit}", 2068 "hrefSchema": { 2069 "$ref": "thing-collection#/definitions/pagination" 2070 }, 2071 "submissionSchema": { 2072 "$ref": "thing#" 2073 }, 2074 "targetSchema": { 2075 "$ref": "thing-collection#" 2076 } 2077 } 2079 Now we see the pagination parameters being accepted as input, so we 2080 can jump to any page within the collection. The link relation type 2081 is a custom one as the generic "collection" link can only be used 2082 with an item as its context, not an entry point or other resource. 2084 9.5.2. Creating the First Item 2086 When we do not have any "thing"s, we do not have any resources with a 2087 relevant "collection" link. Therefore we cannot use a "collection" 2088 link's submission keywords to create the first "thing"; hyper-schemas 2089 must be evaluated with respect to an instance. Since the "elements" 2090 array in the collection instance would be empty, it cannot provide us 2091 with a collection link either. 2093 However, our entry point link can take us to the empty collection, 2094 and we can use the presence of "item" links in the hyper-schema to 2095 recognize that it is a collection. Since the context of the "item" 2096 link is the collection, we simply look for a "self" link with the 2097 same context, which we can then treat as collection for the purposes 2098 of a creation operation. 2100 Presumably, our custom link relation type in the entry point schema 2101 was sufficient to ensure that we have found the right collection. A 2102 client application that recognizes that custom link relation type may 2103 know that it can immediately assume that the target is a collection, 2104 but a generic user agent cannot do so. Despite the presence of a 2105 "-collection" suffix in our example, a generic user agent would have 2106 no way of knowing whether that substring indicates a hypermedia 2107 resource collection, or some other sort of collection. 2109 Once we have recognized the "self" link as being for the correct 2110 collection, we can use its "submissionSchema" and/or 2111 "submissionMediaType" keywords to perform an item creation operation. 2112 [[CREF8: This works perfectly if the collection is unfiltered and 2113 unpaginated. However, one should generally POST to a collection that 2114 will contain the created resource, and a "self" link MUST include any 2115 filters, pagination, or other query parameters. Is it still valid to 2116 POST to such a "self" link even if the resulting item would not match 2117 the filter or appear within that page? See GitHub issue #421 for 2118 further discussion. ]] [[CREF9: Draft-04 of Hyper-Schema defined a 2119 "create" link relation that had the schema, rather than the instance, 2120 as its context. This did not fit into the instance-based link model, 2121 and incorrectly used an operation name for a link relation type. 2122 However, defining a more correctly designed link from the schema to 2123 the collection instance may be one possible approach to solving this. 2124 Again, see GitHub issue #421 for more details. ]] 2126 10. Security Considerations 2128 JSON Hyper-Schema defines a vocabulary for JSON Schema core and 2129 concerns all the security considerations listed there. As a link 2130 serialization format, the security considerations of RFC 8288 Web 2131 Linking [RFC8288] also apply, with appropriate adjustments (e.g. 2132 "anchor" as an LDO keyword rather than an HTTP Link header 2133 attribute). 2135 10.1. Target Attributes 2137 As stated in Section 6.5, all LDO keywords describing the target 2138 resource are advisory and MUST NOT be used in place of the 2139 authoritative information supplied by the target resource in response 2140 to an operation. Target resource responses SHOULD indicate their own 2141 hyper-schema, which is authoritative. 2143 If the hyper-schema in the target response matches (by "$id") the 2144 hyper-schema in which the current LDO was found, then the target 2145 attributes MAY be considered authoritative. [[CREF10: Need to add 2146 something about the risks of spoofing by "$id", but given that other 2147 parts of the specification discourage always re-downloading the 2148 linked schema, the risk mitigation options are unclear. ]] 2150 User agents or client applications MUST NOT use the value of 2151 "targetSchema" to aid in the interpretation of the data received in 2152 response to following the link, as this leaves "safe" data open to 2153 re-interpretation. 2155 When choosing how to interpret data, the type information provided by 2156 the server (or inferred from the filename, or any other usual method) 2157 MUST be the only consideration, and the "targetMediaType" property of 2158 the link MUST NOT be used. User agents MAY use this information to 2159 determine how they represent the link or where to display it (for 2160 example hover-text, opening in a new tab). If user agents decide to 2161 pass the link to an external program, they SHOULD first verify that 2162 the data is of a type that would normally be passed to that external 2163 program. 2165 This is to guard against re-interpretation of "safe" data, similar to 2166 the precautions for "targetSchema". 2168 Protocol meta-data values conveyed in "targetHints" MUST NOT be 2169 considered authoritative. Any security considerations defined by the 2170 protocol that may apply based on incorrect assumptions about meta- 2171 data values apply. 2173 Even when no protocol security considerations are directly 2174 applicable, implementations MUST be prepared to handle responses that 2175 do not match the link's "targetHints" values. 2177 10.2. "self" Links 2179 When link relation of "self" is used to denote a full representation 2180 of an object, the user agent SHOULD NOT consider the representation 2181 to be the authoritative representation of the resource denoted by the 2182 target URI if the target URI is not equivalent to or a sub-path of 2183 the URI used to request the resource representation which contains 2184 the target URI with the "self" link. [[CREF11: It is no longer 2185 entirely clear what was intended by the "sub-path" option in this 2186 paragraph. It may have been intended to allow "self" links for 2187 embedded item representations in a collection, which usually have 2188 target URIs that are sub-paths of that collection's URI, to be 2189 considered authoritative. However, this is simply a common design 2190 convention and does not appear to be based in RFC 3986 or any other 2191 guidance on URI usage. See GitHub issue #485 for further discussion. 2192 ]] 2194 11. Acknowledgments 2196 Thanks to Gary Court, Francis Galiegue, Kris Zyp, and Geraint Luff 2197 for their work on the initial drafts of JSON Schema. 2199 Thanks to Jason Desrosiers, Daniel Perrett, Erik Wilde, Ben Hutton, 2200 Evgeny Poberezkin, Brad Bowman, Gowry Sankar, Donald Pipowitch, Dave 2201 Finlay, and Denis Laxalde for their submissions and patches to the 2202 document. 2204 12. References 2206 12.1. Normative References 2208 [json-schema] 2209 Wright, A. and H. Andrews, "JSON Schema: A Media Type for 2210 Describing JSON Documents", draft-handrews-json-schema-00 2211 (work in progress), November 2017. 2213 [json-schema-validation] 2214 Wright, A., Andrews, H., and G. Luff, "JSON Schema 2215 Validation: A Vocabulary for Structural Validation of 2216 JSON", draft-handrews-json-schema-validation-00 (work in 2217 progress), November 2017. 2219 [relative-json-pointer] 2220 Luff, G. and H. Andrews, "Relative JSON Pointers", draft- 2221 handrews-relative-json-pointer-01 (work in progress), 2222 January 2018. 2224 [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate 2225 Requirement Levels", BCP 14, RFC 2119, 2226 DOI 10.17487/RFC2119, March 1997, 2227 . 2229 [RFC3986] Berners-Lee, T., Fielding, R., and L. Masinter, "Uniform 2230 Resource Identifier (URI): Generic Syntax", STD 66, 2231 RFC 3986, DOI 10.17487/RFC3986, January 2005, 2232 . 2234 [RFC4287] Nottingham, M., Ed. and R. Sayre, Ed., "The Atom 2235 Syndication Format", RFC 4287, DOI 10.17487/RFC4287, 2236 December 2005, . 2238 [RFC6570] Gregorio, J., Fielding, R., Hadley, M., Nottingham, M., 2239 and D. Orchard, "URI Template", RFC 6570, 2240 DOI 10.17487/RFC6570, March 2012, 2241 . 2243 [RFC6573] Amundsen, M., "The Item and Collection Link Relations", 2244 RFC 6573, DOI 10.17487/RFC6573, April 2012, 2245 . 2247 [RFC6901] Bryan, P., Ed., Zyp, K., and M. Nottingham, Ed., 2248 "JavaScript Object Notation (JSON) Pointer", RFC 6901, 2249 DOI 10.17487/RFC6901, April 2013, 2250 . 2252 [RFC8288] Nottingham, M., "Web Linking", RFC 8288, 2253 DOI 10.17487/RFC8288, October 2017, 2254 . 2256 12.2. Informative References 2258 [I-D.reschke-http-jfv] 2259 Reschke, J., "A JSON Encoding for HTTP Header Field 2260 Values", draft-reschke-http-jfv-06 (work in progress), 2261 June 2017. 2263 [RFC2046] Freed, N. and N. Borenstein, "Multipurpose Internet Mail 2264 Extensions (MIME) Part Two: Media Types", RFC 2046, 2265 DOI 10.17487/RFC2046, November 1996, 2266 . 2268 [RFC4151] Kindberg, T. and S. Hawke, "The 'tag' URI Scheme", 2269 RFC 4151, DOI 10.17487/RFC4151, October 2005, 2270 . 2272 [RFC5789] Dusseault, L. and J. Snell, "PATCH Method for HTTP", 2273 RFC 5789, DOI 10.17487/RFC5789, March 2010, 2274 . 2276 [RFC6068] Duerst, M., Masinter, L., and J. Zawinski, "The 'mailto' 2277 URI Scheme", RFC 6068, DOI 10.17487/RFC6068, October 2010, 2278 . 2280 [RFC7230] Fielding, R., Ed. and J. Reschke, Ed., "Hypertext Transfer 2281 Protocol (HTTP/1.1): Message Syntax and Routing", 2282 RFC 7230, DOI 10.17487/RFC7230, June 2014, 2283 . 2285 [RFC7231] Fielding, R., Ed. and J. Reschke, Ed., "Hypertext Transfer 2286 Protocol (HTTP/1.1): Semantics and Content", RFC 7231, 2287 DOI 10.17487/RFC7231, June 2014, 2288 . 2290 [RFC7807] Nottingham, M. and E. Wilde, "Problem Details for HTTP 2291 APIs", RFC 7807, DOI 10.17487/RFC7807, March 2016, 2292 . 2294 Appendix A. Using JSON Hyper-Schema in APIs 2296 Hypermedia APIs, which follow the constraints of the REST 2297 architectural style, enable the creation of generic user agents. 2298 Such a user agent has no application-specific knowledge. Rather, it 2299 understands pre-defined media types, URI schemes, protocols, and link 2300 relations, often by recognizing these and coordinating the use of 2301 existing software that implements support for them. Client 2302 applications can then be built on top of such a user agent, focusing 2303 on their own semantics and logic rather than the mechanics of the 2304 interactions. 2306 Hyper-schema is only concerned with one resource and set of 2307 associated links at a time. Just as a web browser works with only 2308 one HTML page at a time, with no concept of whether or how that page 2309 functions as part of a "site", a hyper-schema-aware user agent works 2310 with one resource at a time, without any concept of whether or how 2311 that resource fits into an API. 2313 Therefore, hyper-schema is suitable for use within an API, but is not 2314 suitable for the description of APIs as complete entities in their 2315 own right. There is no way to describe concepts at the API scope, 2316 rather than the resource and link scope, and such descriptions are 2317 outside of the boundaries of JSON Hyper-Schema. 2319 A.1. Resource Evolution With Hyper-Schema 2321 Since a given JSON Hyper-Schema is used with a single resource at a 2322 single point in time, it has no inherent notion of versioning. 2323 However, a given resource can change which schema or schemas it uses 2324 over time, and the URIs of these schemas can be used to indicate 2325 versioning information. When used with a media type that supports 2326 indicating a schema with a media type parameter, these versioned 2327 schema URIs can be used in content negotiation. 2329 A resource can indicate that it is an instance of multiple schemas, 2330 which allows supporting multiple compatible versions simultaneously. 2331 A client application can then make use of the hyper-schema that it 2332 recognizes, and ignore newer or older versions. 2334 A.2. Responses and Errors 2336 Because a hyper-schema represents a single resource at a time, it 2337 does not provide for an enumeration of all possible responses to 2338 protocol operations performed with links. Each response, including 2339 errors, is considered its own (possibly anonymous) resource, and 2340 should identify its own hyper-schema, and optionally use an 2341 appropriate media type such as RFC 7807's "application/problem+json" 2343 [RFC7807], to allow the user agent or client application to interpret 2344 any information that is provided beyond the protocol's own status 2345 reporting. 2347 A.3. Static Analysis of an API's Hyper-Schemas 2349 It is possible to statically analyze a set of hyper-schemas without 2350 instance data in order to generate output such as documentation or 2351 code. However, the full feature set of both validation and hyper- 2352 schema cannot be accessed without runtime instance data. 2354 This is an intentional design choice to provide the maximum runtime 2355 flexibility for hypermedia systems. JSON Schema as a media type 2356 allows for establishing additional vocabularies for static analysis 2357 and content generation, which are not addressed in this 2358 specification. Additionally, individual systems may restrict their 2359 usage to subsets that can be analyzed statically if full design-time 2360 description is a goal. [[CREF12: Vocabularies for API documentation 2361 and other purposes have been proposed, and contributions are welcome 2362 at https://github.com/json-schema-org/json-schema-vocabularies ]] 2364 Appendix B. ChangeLog 2366 [[CREF13: This section to be removed before leaving Internet-Draft 2367 status.]] 2369 draft-handrews-json-schema-hyperschema-01 2371 * This draft is purely a bug fix with no functional changes 2373 * Fixed erroneous meta-schema URI (draft-07, not draft-07-wip) 2375 * Removed stray "work in progress" language left over from review 2376 period 2378 * Fixed missing trailing "/" in various "base" examples 2380 * Fixed incorrect draft name in changelog (luff-*-00, not -01) 2382 * Update relative pointer ref to handrews-*-01, also purely a bug 2383 fix 2385 draft-handrews-json-schema-hyperschema-00 2387 * Top to bottom reorganization and rewrite 2389 * Group keywords per RFC 8288 context/relation/target/target 2390 attributes 2392 * Additional keyword groups for template resolution and 2393 describing input 2395 * Clarify implementation requirements with a suggested output 2396 format 2398 * Expanded overview to provide context 2400 * Consolidated examples into their own section, illustrate real- 2401 world patterns 2403 * Consolidated HTTP guidance in its own section 2405 * Added a subsection on static analysis of hyper-schemas 2407 * Consolidated security concerns in their own section 2409 * Added an appendix on usage in APIs 2411 * Moved "readOnly" to the validation specification 2413 * Moved "media" to validation as 2414 "contentMediaType"/"contentEncoding" 2416 * Renamed "submissionEncType" to "submissionMediaType" 2418 * Renamed "mediaType" to "targetMediaType" 2420 * Added "anchor" and "anchorPointer" 2422 * Added "templatePointers" and "templateRequired" 2424 * Clarified how "hrefSchema" is used 2426 * Added "targetHints" and "headerSchema" 2428 * Added guidance on "self", "collection" and "item" link usage 2430 * Added "description" as an LDO keyword 2432 * Added "$comment" in LDOs to match the schema keyword 2434 draft-wright-json-schema-hyperschema-01 2436 * Fixed examples 2438 * Added "hrefSchema" for user input to "href" URI Templates 2439 * Removed URI Template pre-processing 2441 * Clarified how links and data submission work 2443 * Clarified how validation keywords apply hyper-schema keywords 2444 and links 2446 * Clarified HTTP use with "targetSchema" 2448 * Renamed "schema" to "submissionSchema" 2450 * Renamed "encType" to "submissionEncType" 2452 * Removed "method" 2454 draft-wright-json-schema-hyperschema-00 2456 * "rel" is now optional 2458 * rel="self" no longer changes URI base 2460 * Added "base" keyword to change instance URI base 2462 * Removed "root" link relation 2464 * Removed "create" link relation 2466 * Removed "full" link relation 2468 * Removed "instances" link relation 2470 * Removed special behavior for "describedBy" link relation 2472 * Removed "pathStart" keyword 2474 * Removed "fragmentResolution" keyword 2476 * Updated references to JSON Pointer, HTML 2478 * Changed behavior of "method" property to align with hypermedia 2479 best current practices 2481 draft-luff-json-hyper-schema-00 2483 * Split from main specification. 2485 Authors' Addresses 2487 Henry Andrews (editor) 2488 Cloudflare, Inc. 2489 San Francisco, CA 2490 USA 2492 EMail: henry@cloudflare.com 2494 Austin Wright (editor) 2496 EMail: aaa@bzfx.net