idnits 2.17.1 draft-handrews-json-schema-hyperschema-02.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 (September 16, 2019) is 1684 days in the past. Is this intentional? Checking references for intended status: Informational ---------------------------------------------------------------------------- -- Looks like a reference, but probably isn't: '456' on line 1740 == 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 4 Intended status: Informational A. Wright, Ed. 5 Expires: March 19, 2020 September 16, 2019 7 JSON Hyper-Schema: A Vocabulary for Hypermedia Annotation of JSON 8 draft-handrews-json-schema-hyperschema-02 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 March 19, 2020. 48 Copyright Notice 50 Copyright (c) 2019 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 . . . . . . . . . . . . . . . . . . . . . . . 8 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 . . . . . . . . . . . . . . . . . . . . . . . 10 77 6.1.2. anchorPointer . . . . . . . . . . . . . . . . . . . . 10 78 6.2. Link Relation Type . . . . . . . . . . . . . . . . . . . 10 79 6.2.1. rel . . . . . . . . . . . . . . . . . . . . . . . . . 11 80 6.2.2. "self" Links . . . . . . . . . . . . . . . . . . . . 11 81 6.2.3. "collection" and "item" Links . . . . . . . . . . . . 11 82 6.2.4. Using Extension Relation Types . . . . . . . . . . . 12 83 6.3. Link Target . . . . . . . . . . . . . . . . . . . . . . . 12 84 6.3.1. href . . . . . . . . . . . . . . . . . . . . . . . . 12 85 6.4. Adjusting URI Template Resolution . . . . . . . . . . . . 12 86 6.4.1. templatePointers . . . . . . . . . . . . . . . . . . 13 87 6.4.2. templateRequired . . . . . . . . . . . . . . . . . . 13 88 6.5. Link Target Attributes . . . . . . . . . . . . . . . . . 13 89 6.5.1. title . . . . . . . . . . . . . . . . . . . . . . . . 13 90 6.5.2. description . . . . . . . . . . . . . . . . . . . . . 13 91 6.5.3. targetMediaType . . . . . . . . . . . . . . . . . . . 14 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 . . . 17 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 . . . . . . . . . . . . . . . . . . . . . 20 102 7.2.1. Populating Template Data From the Instance . . . . . 21 103 7.2.2. Accepting Input for Template Data . . . . . . . . . . 22 104 7.2.3. Encoding Data as Strings . . . . . . . . . . . . . . 23 105 7.3. Providing Access to LDO Keywords . . . . . . . . . . . . 24 106 7.4. Requests . . . . . . . . . . . . . . . . . . . . . . . . 24 107 7.5. Responses . . . . . . . . . . . . . . . . . . . . . . . . 25 108 7.6. Streaming Parsers . . . . . . . . . . . . . . . . . . . . 26 109 8. JSON Hyper-Schema and HTTP . . . . . . . . . . . . . . . . . 26 110 8.1. One Link Per Target and Relation Type . . . . . . . . . . 27 111 8.2. "targetSchema" and HTTP . . . . . . . . . . . . . . . . . 27 112 8.3. HTTP POST and the "submission*" keywords . . . . . . . . 28 113 8.4. Optimizing HTTP Discoverability With "targetHints" . . . 28 114 8.5. Advertising HTTP Features With "headerSchema" . . . . . . 29 115 8.6. Creating Resources Through Collections . . . . . . . . . 30 116 8.7. Content Negotiation and Schema Evolution . . . . . . . . 30 117 9. Examples . . . . . . . . . . . . . . . . . . . . . . . . . . 31 118 9.1. Entry Point Links, No Templates . . . . . . . . . . . . . 31 119 9.2. Individually Identified Resources . . . . . . . . . . . . 33 120 9.3. Submitting a Payload and Accepting URI Input . . . . . . 34 121 9.4. "anchor", "base" and URI Template Resolution . . . . . . 37 122 9.5. Collections . . . . . . . . . . . . . . . . . . . . . . . 40 123 9.5.1. Pagination . . . . . . . . . . . . . . . . . . . . . 45 124 9.5.2. Creating the First Item . . . . . . . . . . . . . . . 48 125 10. Security Considerations . . . . . . . . . . . . . . . . . . . 49 126 10.1. Target Attributes . . . . . . . . . . . . . . . . . . . 49 127 10.2. "self" Links . . . . . . . . . . . . . . . . . . . . . . 50 128 11. Acknowledgments . . . . . . . . . . . . . . . . . . . . . . . 51 129 12. References . . . . . . . . . . . . . . . . . . . . . . . . . 51 130 12.1. Normative References . . . . . . . . . . . . . . . . . . 51 131 12.2. Informative References . . . . . . . . . . . . . . . . . 52 132 Appendix A. Using JSON Hyper-Schema in APIs . . . . . . . . . . 54 133 A.1. Resource Evolution With Hyper-Schema . . . . . . . . . . 54 134 A.2. Responses and Errors . . . . . . . . . . . . . . . . . . 54 135 A.3. Static Analysis of an API's Hyper-Schemas . . . . . . . . 55 136 Appendix B. ChangeLog . . . . . . . . . . . . . . . . . . . . . 55 137 Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 58 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://example.com/api/", then 216 "https://example.com/api/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.1 of the JSON Schema core specification 227 [json-schema]. 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. Note that invalid links 249 can occur when using keywords such as "if" or "oneOf" (from the 250 Core specification) to describe links that are conditional on the 251 representation's structure or value. 253 generic user agent A user agent which can be used to interact with 254 any resource, from any server, from among the standardized link 255 relations, media types, URI schemes, and protocols that it 256 supports; though it may be extendible to specially handle 257 particular profiles of media types. 259 client application An application which uses a hypermedia system for 260 a specific purpose. Such an application may also be its own user 261 agent, or it may be built on top of a generic user agent. A 262 client application is programmed with knowledge of link relations, 263 media types, URI schemes, protocols, and data structures that are 264 specific to the application's domain. 266 client input Data provided through a user agent, and most often also 267 through a client application. Such data may be requested from a 268 user interactively, or provided before interaction in forms such 269 as command-line arguments, configuration files, or hardcoded 270 values in source code. 272 operation A specific use of a hyperlink, such as making a network 273 request (for a URI with a scheme such as "http://" that indicates 274 a protocol) or otherwise taking action based on a link (reading 275 data from a "data:" URI, or constructing an email message based on 276 a "mailto:" link). For protocols such as HTTP that support 277 multiple methods, each method is considered to be a separate 278 operation on the same link. 280 3.2. Functionality 282 A JSON Hyper-Schema implementation is able to take a hyper-schema, an 283 instance, and in some cases client input, and produce a set of fully 284 resolved valid links. As defined by RFC 8288, section 2 [RFC8288], a 285 link consists of a context, a typed relation, a target, and 286 optionally additional target attributes. 288 The relation type and target attributes are taken directly from each 289 link's Link Description Object. The context and target identifiers 290 are constructed from some combination of URI Templates, instance 291 data, and (in the case of the target identifier) client input. 293 The target is always fully identified by a URI. Due to the lack of a 294 URI fragment identifier syntax for application/json and many other 295 media types that can be used with JSON Hyper-Schema, the context may 296 be only partially identified by a URI. In such cases, the remaining 297 identification will be provided as a JSON Pointer. 299 A few IANA-registered link relation types are given specific 300 semantics in a JSON Hyper-Schema document. A "self" link is used to 301 interact with the resource that the instance document represents, 302 while "collection" and "item" links identify resources for which 303 collection-specific semantics can be assumed. 305 4. Meta-Schemas and Output Schema 307 The current URI for the JSON Hyper-Schema meta-schema is 308 . 310 The current URI for this vocabulary, known as the Hyper-Schema 311 vocabulary, is: . 314 The current URI for the corresponding meta-schema, which differs from 315 the convenience meta-schema above in that it describes only the 316 hyper-schema keywords ("base" and "link") is: . 319 The link description format (Section 6) can be used without JSON 320 Schema, and use of this format can be declared by referencing the 321 normative link description schema as the schema for the data 322 structure that uses the links. The URI of the normative link 323 description schema is: . 326 JSON Hyper-Schema implementations are free to provide output in any 327 format. However, a specific format is defined for use in the 328 conformance test suite, which is also used to illustrate points in 329 the "Implementation Requirements" (Section 7), and to show the output 330 generated by examples (Section 9). It is RECOMMENDED that 331 implementations be capable of producing output in this format to 332 facilitated testing. The URI of the JSON Schema describing the 333 recommended output format is . 336 Updated vocabulary and meta-schema URIs MAY be published between 337 specification drafts in order to correct errors. Implementations 338 SHOULD consider URIs dated after this specification draft and before 339 the next to indicate the same syntax and semantics as those listed 340 here. 342 5. Schema Keywords 344 Hyper-schema keywords from all schemas that are applicable to a 345 position in an instance, as defined by Section 3.1 of JSON Schema 346 core [json-schema], can be used with that instance. 348 When multiple subschemas are applicable to a given sub-instance, all 349 "link" arrays MUST be combined, in any order, into a single set. 350 Each object in the resulting set MUST retain its own list of 351 applicable "base" values, in resolution order, from the same schema 352 and any parent schemas. 354 As with all JSON Schema keywords, all keywords described in this 355 section are optional. The minimal valid JSON Hyper-schema is the 356 blank object. 358 5.1. base 360 If present, this keyword MUST be first resolved as a URI Template 361 (Section 7.2), and then MUST be resolved as a URI Reference against 362 the current URI base of the instance. The result MUST be set as the 363 new URI base for the instance while processing the sub-schema 364 containing "base" and all sub-schemas within it. 366 The process for resolving the "base" template can be different when 367 being resolved for use with "anchor" than when being resolved for use 368 with "href", which is explained in detail in the URI Templating 369 section. 371 5.2. links 373 The "links" property of schemas is used to associate Link Description 374 Objects with instances. The value of this property MUST be an array, 375 and the items in the array must be Link Description Objects, as 376 defined below. 378 6. Link Description Object 380 A Link Description Object (LDO) is a serialization of the abstract 381 link model defined in RFC 8288, section 2 [RFC8288]. As described in 382 that document, a link consists of a context, a relation type, a 383 target, and optionally target attributes. JSON Hyper-Schema's LDO 384 provides all of these, along with additional features using JSON 385 Schema to describe input for use with the links in various ways. 387 Due to the use of URI Templates to identify link contexts and 388 targets, as well as optional further use of client input when 389 identifying targets, an LDO is a link template that may resolve to 390 multiple links when used with a JSON instance document. 392 A specific use of an LDO, typically involving a request and response 393 across a protocol, is referred to as an operation. For many 394 protocols, multiple operations are possible on any given link. The 395 protocol is indicated by the target's URI scheme. Note that not all 396 URI schemes indicate a protocol that can be used for communications, 397 and even resources with URI schemes that do indicate such protocols 398 need not be available over that protocol. 400 A Link Description Object MUST be an object, and the "href" 401 (Section 6.3.1) and "rel" (Section 6.2.1) properties MUST be present. 402 Each keyword is covered briefly in this section, with additional 403 usage explanation and comprehensive examples given later in the 404 document. 406 6.1. Link Context 408 In JSON Hyper-Schema, the link's context resource is, by default, the 409 sub-instance to which it is attached (as defined by Section 3.1 of 410 the JSON Schema core specification [json-schema]). This is often not 411 the entire instance document. This default context can be changed 412 using the keywords in this section. 414 Depending on the media type of the instance, it may or may not be 415 possible to assign a URI to the exact default context resource. In 416 particular, application/json does not define a URI fragment 417 resolution syntax, so properties or array elements within a plain 418 JSON document cannot be fully identified by a URI. When it is not 419 possible to produce a complete URI, the position of the context 420 SHOULD be conveyed by the URI of the instance document, together with 421 a separate plain-string JSON Pointer. 423 Implementations MUST be able to construct the link context's URI, and 424 (if necessary for full identification), a JSON Pointer in string 425 representation form as per RFC 6901, section 5 [RFC6901] in place of 426 a URI fragment. The process for constructing a URI based on a URI 427 template is given in the URI Templating (Section 7.2) section. 429 6.1.1. anchor 431 This property sets the context URI of the link. The value of the 432 property is a URI Template [RFC6570], and the resulting URI-reference 433 [RFC3986] MUST be resolved against the base URI of the instance. 435 The URI is computed from the provided URI template using the same 436 process described for the "href" (Section 6.3.1) property, with the 437 exception that "hrefSchema" (Section 6.6.1) MUST NOT be applied. 438 Unlike target URIs, context URIs do not accept user input. 440 6.1.2. anchorPointer 442 This property changes the point within the instance that is 443 considered to be the context resource of the link. The value of the 444 property MUST be a valid JSON Pointer in JSON String representation 445 form, or a valid Relative JSON Pointer [relative-json-pointer] which 446 is evaluated relative to the default context. 448 While an alternate context with a known URI is best set with the 449 "anchor" (Section 6.1.1) keyword, the lack of a fragment identifier 450 syntax for application/json means that it is usually not possible to 451 change the context within a JSON instance using a URI. 453 Even in "+json" media types that define JSON Pointer as a fragment 454 identifier syntax, if the default context is nested within an array, 455 it is not possible to obtain the index of the default context's 456 position in that array in order to construct a pointer to another 457 property in that same nested JSON object. This will be demonstrated 458 in the examples. 460 The result of processing this keyword SHOULD be a URI fragment if the 461 media type of the instance allows for such a fragment. Otherwise it 462 MUST be a string-encoded JSON Pointer. 464 6.2. Link Relation Type 466 The link's relation type identifies its semantics. It is the primary 467 means of conveying how an application can interact with a resource. 469 Relationship definitions are not normally media type dependent, and 470 users are encouraged to utilize the most suitable existing accepted 471 relation definitions. 473 6.2.1. rel 475 The value of this property MUST be either a string or an array of 476 strings. If the value is an array, it MUST contain at least one 477 string. 479 Each string MUST be a single Link Relation Type as defined in RFC 480 8288, Section 2.1, including the restriction that additional 481 semantics SHOULD NOT be inferred based upon the presence or absence 482 of another link relation type. 484 This property is required. 486 6.2.2. "self" Links 488 A "self" link, as originally defined by Section 4.2.7.2 of RFC 4287 489 [RFC4287], indicates that the target URI identifies a resource 490 equivalent to the link context. In JSON Hyper-Schema, a "self" link 491 MUST be resolvable from the instance, and therefore "hrefSchema" MUST 492 NOT be present. 494 Hyper-schema authors SHOULD use "templateRequired" to ensure that the 495 "self" link has all instance data that is needed for use. 497 A hyper-schema implementation MUST recognize that a link with 498 relation type "self" that has the entire current instance document as 499 its context describes how a user agent can interact with the resource 500 represented by that instance document. 502 6.2.3. "collection" and "item" Links 504 RFC 6573 [RFC6573] defines and registers the "item" and "collection" 505 link relation types. JSON Hyper-Schema imposes additional semantics 506 on collection resources indicated by these types. 508 Implementations MUST recognize the target of a "collection" link and 509 the context of an "item" link as collections. 511 A well-known design pattern in hypermedia is to use a collection 512 resource to create a member of the collection and give it a server- 513 assigned URI. If the protocol indicated by the URI scheme defines a 514 specific method that is suited to creating a resource with a server- 515 assigned URI, then a collection resource, as identified by these link 516 relation types, MUST NOT define semantics for that method that 517 conflict with the semantics of creating a collection member. 518 Collection resources MAY implement item creation via such a protocol 519 method, and user agents MAY assume that any such operation, if it 520 exists, has item creation semantics. 522 As such a method would correspond to JSON Hyper-Schema's data 523 submission concept, the "submissionSchema" (Section 6.6.4.2) field 524 for the link SHOULD be compatible with the schema of the 525 representation of the collection's items, as indicated by the "item" 526 link's target resource or the "self" link of the "collection" link's 527 context resource. 529 6.2.4. Using Extension Relation Types 531 When no registered relation (aside from "related") applies, users are 532 encouraged to mint their own extension relation types, as described 533 in section 2.1.2 of RFC 8288 [RFC8288]. The simplest approaches for 534 choosing link relation type URIs are to either use a URI scheme that 535 is already in use to identify the system's primary resources, or to 536 use a human-readable, non-dereferenceable URI scheme such as "tag", 537 defined by RFC 4151 [RFC4151]. 539 Extension relation type URIs need not be dereferenceable, even when 540 using a scheme that allows it. 542 6.3. Link Target 544 The target URI template is used to identify the link's target, 545 potentially making use of instance data. Additionally, with 546 "hrefSchema" (Section 6.6.1), this template can identify a set of 547 possible target resources to use based on client input. The full 548 process of resolving the URI template, with or without client input, 549 is covered in the URI Templating (Section 7.2) section. 551 6.3.1. href 553 The value of the "href" link description property is a template used 554 to determine the target URI of the related resource. The value of 555 the instance property MUST be resolved as a URI-reference [RFC3986] 556 against the base URI of the instance. 558 This property is REQUIRED. 560 6.4. Adjusting URI Template Resolution 562 The keywords in this section are used when resolving all URI 563 Templates involved in hyper-schema: "base", "anchor", and "href". 564 See the URI Templating (Section 7.2) section for the complete 565 template resolution algorithm. 567 Note that when resolving a "base" template, the attachment point from 568 which resolution begins is the attachment point of the "href" or 569 "anchor" keyword being resolved which requires "base" templates to be 570 resolved, not the attachment point of the "base" keyword itself. 572 6.4.1. templatePointers 574 The value of the "templatePointers" link description property MUST be 575 an object. Each property value in the object MUST be a valid JSON 576 Pointer [RFC6901], or a valid Relative JSON Pointer 577 [relative-json-pointer] which is evaluated relative to the attachment 578 point of the link for which the template is being resolved. 580 For each property name in the object that matches a variable name in 581 the template being resolved, the value of that property adjusts the 582 starting position of variable resolution for that variable. 583 Properties which do not match template variable names in the template 584 being resolved MUST be ignored. 586 6.4.2. templateRequired 588 The value of this keyword MUST be an array, and the elements MUST be 589 unique. Each element SHOULD match a variable in the link's URI 590 Template, without percent-encoding. After completing the entire URI 591 Template resolution process, if any variable that is present in this 592 array does not have a value, the link MUST NOT be used. 594 6.5. Link Target Attributes 596 All properties in this section are advisory only. While keywords 597 such as "title" and "description" are used primarily to present the 598 link to users, those keywords that predict the nature of a link 599 interaction or response MUST NOT be considered authoritative. The 600 runtime behavior of the target resource MUST be respected whenever it 601 conflicts with the target attributes in the LDO. 603 6.5.1. title 605 This property defines a title for the link. The value MUST be a 606 string. 608 User agents MAY use this title when presenting the link to the user. 610 6.5.2. description 612 This property provides additional information beyond what is present 613 in the title. The value MUST be a string. While a title is 614 preferably short, a description can be used to go into more detail 615 about the purpose and usage of the link. 617 User agents MAY use this description when presenting the link to the 618 user. 620 6.5.3. targetMediaType 622 The value of this property represents the media type RFC 2046 623 [RFC2046], that is expected to be returned when fetching this 624 resource. This property value MAY be a media range instead, using 625 the same pattern defined in RFC 7231, section 5.3.2 - HTTP "Accept" 626 header [RFC7231]. 628 This property is analogous to the "type" property of other link 629 serialization formats. User agents MAY use this information to 630 inform the interface they present to the user before the link is 631 followed, but MUST NOT use this information in the interpretation of 632 the resulting data. Instead, a user agent MUST use the media type 633 given by the response for run-time interpretation. See the section 634 on "Security Concerns" (Section 10) for a detailed examination of 635 mis-use of "targetMediaType". 637 For protocols supporting content-negotiation, implementations MAY 638 choose to describe possible target media types using protocol- 639 specific information in "headerSchema" (Section 6.6.2). If both 640 protocol-specific information and "targetMediaType" are present, then 641 the value of "targetMediaType" MUST be compatible with the protocol- 642 specific information, and SHOULD indicate the media type that will be 643 returned in the absence of content negotiation. 645 When no such protocol-specific information is available, or when the 646 implementation does not recognize the protocol involved, then the 647 value SHOULD be taken to be "application/json". 649 6.5.4. targetSchema 651 This property provides a schema that is expected to describe the link 652 target's representation. Depending on the protocol, the schema may 653 or may not describe the request or response to any particular 654 operation performed with the link. See the JSON Hyper-Schema and 655 HTTP (Section 8) section for an in-depth discussion of how this 656 keyword is used with HTTP. 658 6.5.5. targetHints 660 [[CREF1: This section attempts to strike a balance between 661 comprehensiveness and flexibility by deferring most of its structure 662 to the protocol indicated by the URI scheme. Note that a resource 663 can be identified by a URI with a dereferenceable scheme, yet not be 664 accessible over that protocol. While currently very loose, this 665 section is expected to become more well-defined based on draft 666 feedback, and may change significantly in future drafts. ]] 668 The value of this property is advisory only. It represents 669 information that is expected to be discoverable through interacting 670 with the target resource, typically in the form of protocol-specific 671 control information or meta-data such as headers returned in response 672 to an HTTP HEAD or OPTIONS request. The protocol is determined by 673 the "href" URI scheme, although note that resources are not 674 guaranteed to be accessible over such a protocol. 676 The value of this property SHOULD be an object. The keys to this 677 object SHOULD be lower-cased forms of the control data field names. 678 Each value SHOULD be an array, in order to uniformly handle multi- 679 valued fields. Multiple values MUST be presented as an array, and 680 not as a single string. 682 Protocols with control information not suitable for representation as 683 a JSON object MAY be represented by another data type, such as an 684 array. 686 Values that cannot be understood as part of the indicated protocol 687 MUST be ignored by a JSON Hyper-Schema implementation. Applications 688 MAY make use of such values, but MUST NOT assume interoperability 689 with other implementations. 691 Implementations MUST NOT assume that all discoverable information is 692 accounted for in this object. Client applications MUST properly 693 handle run-time responses that contradict this property's values. 695 Client applications MUST NOT assume that an implementation will 696 automatically take any action based on the value of this property. 698 See "JSON Hyper-Schema and HTTP" (Section 8) for guidance on using 699 this keyword with HTTP and analogous protocols. 701 6.6. Link Input 703 There are four ways to use client input with a link, and each is 704 addressed by a separate link description object keyword. When 705 performing operations, user agents SHOULD ignore schemas that are not 706 relevant to their semantics. 708 6.6.1. hrefSchema 710 The value of the "hrefSchema" link description property MUST be a 711 valid JSON Schema. This schema is used to validate user input or 712 other user agent data for filling out the URI Template in "href" 713 (Section 6.3.1). 715 Omitting "hrefSchema" or setting the entire schema to "false" 716 prevents any user agent data from being accepted. 718 Setting any subschema that applies to a particular variable to the 719 JSON literal value "false" prevents any user agent data from being 720 accepted for that single variable. 722 For template variables that can be resolved from the instance data, 723 if the instance data is valid against all applicable subschemas in 724 "hrefSchema", then it MUST be used to pre-populate the input data set 725 for that variable. 727 Note that even when data is pre-populated from the instance, the 728 validation schema for that variable in "hrefSchema" need not be 729 identical to the validation schema(s) that apply to the instance 730 data's location. This allows for different validation rules for user 731 agent data, such as supporting spelled-out months for date-time 732 input, but using the standard date-time format for storage. 734 After input is accepted, potentially overriding the pre-populated 735 instance data, the resulting data set MUST successfully validate 736 against the value of "hrefSchema". If it does not then the link MUST 737 NOT be used. If it is valid, then the process given in the "URI 738 Templating" section continues with this updated data set. 740 6.6.2. headerSchema 742 [[CREF2: As with "targetHints", this keyword is somewhat under- 743 specified to encourage experimentation and feedback as we try to 744 balance flexibility and clarity. ]] 746 If present, this property is a schema for protocol-specific request 747 headers or analogous control and meta-data. The value of this object 748 MUST be a valid JSON Schema. The protocol is determined by the 749 "href" URI scheme, although note that resources are not guaranteed to 750 be accessible over such a protocol. The schema is advisory only; the 751 target resource's behavior is not constrained by its presence. 753 The purpose of this keyword is to advertise target resource 754 interaction features, and indicate to user agents and client 755 applications what headers and header values are likely to be useful. 756 User agents and client applications MAY use the schema to validate 757 relevant headers, but MUST NOT assume that missing headers or values 758 are forbidden from use. While schema authors MAY set 759 "additionalProperties" to false, this is NOT RECOMMENDED and MUST NOT 760 prevent client applications or user agents from supplying additional 761 headers when requests are made. 763 The exact mapping of the JSON data model into the headers is 764 protocol-dependent. However, in most cases this schema SHOULD 765 specify a type of "object", and the property names SHOULD be lower- 766 cased forms of the control data field names. As with "targetHints", 767 the values SHOULD be described as arrays to allow for multiple 768 values, even if only one value is expected. 770 See the "JSON Hyper-Schema and HTTP" (Section 8) section for detailed 771 guidance on using this keyword with HTTP and analogous protocols. 773 "headerSchema" is applicable to any request method or command that 774 the protocol supports. When generating a request, user agents and 775 client applications SHOULD ignore schemas for headers that are not 776 relevant to that request. 778 6.6.3. Manipulating the Target Resource Representation 780 In JSON Hyper-Schema, "targetSchema" (Section 6.5.4) supplies a non- 781 authoritative description of the target resource's representation. A 782 client application can use "targetSchema" to structure input for 783 replacing or modifying the representation, or as the base 784 representation for building a patch document based on a patch media 785 type. 787 Alternatively, if "targetSchema" is absent or if the client 788 application prefers to only use authoritative information, it can 789 interact with the target resource to confirm or discover its 790 representation structure. 792 "targetSchema" is not intended to describe link operation responses, 793 except when the response semantics indicate that it is a 794 representation of the target resource. In all cases, the schema 795 indicated by the response itself is authoritative. See "JSON Hyper- 796 Schema and HTTP" (Section 8) for detailed examples. 798 6.6.4. Submitting Data for Processing 800 The "submissionSchema" (Section 6.6.4.2) and "submissionMediaType" 801 (Section 6.6.4.1) keywords describe the domain of the processing 802 function implemented by the target resource. Otherwise, as noted 803 above, the submission schema and media type are ignored for 804 operations to which they are not relevant. 806 6.6.4.1. submissionMediaType 808 If present, this property indicates the media type format the client 809 application and user agent should use for the request payload 810 described by "submissionSchema" (Section 6.6.4.2). 812 Omitting this keyword has the same behavior as a value of 813 application/json. 815 Note that "submissionMediaType" and "submissionSchema" are not 816 restricted to HTTP URIs. [[CREF3: This statement might move to 817 wherever the example ends up.]] 819 6.6.4.2. submissionSchema 821 This property contains a schema which defines the acceptable 822 structure of the document to be encoded according to the 823 "submissionMediaType" property and sent to the target resource for 824 processing. This can be viewed as describing the domain of the 825 processing function implemented by the target resource. 827 This is a separate concept from the "targetSchema" (Section 6.5.4) 828 property, which describes the target information resource (including 829 for replacing the contents of the resource in a PUT request), unlike 830 "submissionSchema" which describes the user-submitted request data to 831 be evaluated by the resource. "submissionSchema" is intended for use 832 with requests that have payloads that are not necessarily defined in 833 terms of the target representation. 835 Omitting "submissionSchema" has the same behavior as a value of 836 "true". 838 7. Implementation Requirements 840 At a high level, a conforming implementation will meet the following 841 requirements. Each of these requirements is covered in more detail 842 in the individual keyword sections and keyword group overviews. 844 Note that the requirements around how an implementation MUST 845 recognize "self", "collection", and "item" links are thoroughly 846 covered in the link relation type (Section 6.2) section and are not 847 repeated here. 849 While it is not a mandatory format for implementations, the output 850 format used in the test suite summarizes what needs to be computed 851 for each link before it can be used: 853 contextUri The fully resolved URI (with scheme) of the context 854 resource. If the context is not the entire resource and there is 855 a usable fragment identifier syntax, then the URI includes a 856 fragment. Note that there is no such syntax for application/json. 858 contextPointer The JSON Pointer for the location within the instance 859 of the context resource. If the instance media type supports JSON 860 Pointers as fragment identifiers, this pointer will be the same as 861 the one encoded in the fragment of the "contextUri" field. 863 rel The link relation type. When multiple link relation types 864 appear in the LDO, for the purpose of producing output, they are 865 to be treated as multiple LDOs, each with a single link relation 866 type but otherwise identical. 868 targetUri The fully resolved URI (with a scheme) of the target 869 resource. If the link accepts input, this can only be produced 870 once the input has been supplied. 872 hrefInputTemplates The list of partially resolved URI references for 873 a link that accepts input. The first entry in the list is the 874 partially resolved "href". The additional entries, if any, are 875 the partially resolved "base" values ordered from the most 876 immediate out to the root of the schema. Template variables that 877 are pre-populated in the input are not resolved at this stage, as 878 the pre-populated value can be overridden. 880 hrefPrepopulatedInput The data set that the user agent should use to 881 prepopulate any input mechanism before accepting client input. If 882 input is to be accepted but no fields are to be pre-populated, 883 then this will be an empty object. 885 attachmentPointer The JSON Pointer for the location within the 886 instance to which the link is attached. By default, "contextUri" 887 and "attachmentPointer" are the same, but "contextUri" can be 888 changed by LDO keywords, while "attachmentPointer" cannot. 890 Other LDO keywords that are not involved in producing the above 891 information are included exactly as they appear when producing output 892 for the test suite. Those fields will not be further discussed here 893 unless specifically relevant. 895 7.1. Link Discovery and Look-Up 897 Before links can be used, they must be discovered by applying the 898 hyper-schema to the instance and finding all applicable and valid 899 links. Note that in addition to collecting valid links, any "base" 900 (Section 5.1) values necessary to resolve each LDO's URI Templates 901 must also be located and associated with the LDO through whatever 902 mechanism is most useful for the implementation's URI Template 903 resolution process. 905 And implementation MUST support looking up links by either their 906 attachment pointer or context pointer, either by performing the look- 907 up or by providing the set of all links with both pointers determined 908 so that user agents can implement the look-up themselves. 910 When performing look-ups by context pointer, links that are attached 911 to elements of the same array MUST be returned in the same order as 912 the array elements to which they are attached. 914 7.2. URI Templating 916 Three hyper-schema keywords are URI Templates [RFC6570]: "base", 917 "anchor", and "href". Each are resolved separately to URI- 918 references, and then the anchor or href URI-reference is resolved 919 against the base (which is itself resolved against earlier bases as 920 needed, each of which was first resolved from a URI Template to a 921 URI-reference). 923 All three keywords share the same algorithm for resolving variables 924 from instance data, which makes use of the "templatePointers" and 925 "templateRequired" keywords. When resolving "href", both it and any 926 "base" templates needed for resolution to an absolute URI, the 927 algorithm is modified to optionally accept user input based on the 928 "hrefSchema" keyword. 930 For each URI Template (T), the following pseudocode describes an 931 algorithm for resolving T into a URI-reference (R). For the purpose 932 of this algorithm: 934 o "ldo.templatePointers" is an empty object if the keyword was not 935 present and "ldo.templateRequired" is likewise an empty array. 937 o "attachmentPointer" is the absolute JSON Pointer for the 938 attachment location of the LDO. 940 o "getApplicableSchemas()" returns an iterable set of all 941 (sub)schemas that apply to the attachment point in the instance. 943 This algorithm should be applied first to either "href" or "anchor", 944 and then as needed to each successive "base". The order is 945 important, as it is not always possible to tell whether a template 946 will resolve to a full URI or a URI-reference. 948 In English, the high-level algorithm is: 950 1. Populate template variable data from the instance 952 2. If input is desired, accept input 954 3. Check that all required variables have a value 956 4. Encode values into strings and fill out the template 958 This is the high-level algorithm as pseudocode. "T" comes from 959 either "href" or "anchor" within the LDO, or from "base" in a 960 containing schema. Pseudocode for each step follows. 961 "initialTemplateKeyword" indicates which of the two started the 962 process (since "base" is always resolved in order to finish resolving 963 one or the other of those keywords). 965 templateData = populateDataFromInstance(T, ldo, instance) 967 if initialTemplateKeyword == "href" and ldo.hrefSchema exists: 968 inputData = acceptInput(ldo, instance, templateData) 969 for varname in inputData: 970 templateData[varname] = inputData[varname] 972 for varname in ldo.templateRequired: 973 if not exists templateData[varname] 974 fatal("Missing required variable(s)") 976 templateData = stringEncode(templateData) 977 R = rfc6570ResolutionAlgorithm(T, templateData) 979 7.2.1. Populating Template Data From the Instance 981 This step looks at various locations in the instance for variable 982 values. For each variable: 984 1. Use "templatePointers" to find a value if the variable appears in 985 that keyword's value 987 2. Otherwise, look for a property name matching the variable in the 988 instance location to which the link is attached 990 3. In either case, if there is a value at the location, put it in 991 the template resolution data set 993 for varname in T: 994 varname = rfc3986PercentDecode(varname) 995 if varname in ldo.templatePointers: 996 valuePointer = templatePointers[varname] 997 if valuePointer is relative: 998 valuePointer = resolveRelative(attachmentPointer, 999 valuePointer) 1000 else 1001 valuePointer = attachmentPointer + "/" + varname 1003 value = instance.valueAt(valuePointer) 1004 if value is defined: 1005 templateData[varname] = value 1007 7.2.2. Accepting Input for Template Data 1009 This step is relatively complex, as there are several cases to 1010 support. Some variables will forbid input and some will allow it. 1011 Some will have initial values that need to be presented in the input 1012 interface, and some will not. 1014 1. Determine which variables can accept input 1016 2. Pre-populate the input data set if the template resolution data 1017 set has a value 1019 3. Accept input (present a web form, make a callback, etc.) 1021 4. Validate the input data set, (not the template resolution data 1022 set) 1024 5. Put the input in the template resolution data set, overriding any 1025 existing values 1027 "InputForm" represents whatever sort of input mechanism is 1028 appropriate. This may be a literal web form, or may be a more 1029 programmatic construct such as a callback function accepting specific 1030 fields and data types, with the given initial values, if any. 1032 form = new InputForm() 1033 for varname in T: 1034 useField = true 1035 useInitialData = true 1036 for schema in getApplicableSchemas(ldo.hrefSchema, 1037 "/" + varname): 1038 if schema is false: 1039 useField = false 1040 break 1042 if varname in templateData and 1043 not isValid(templateData[varname], schema)): 1044 useInitialData = false 1045 break 1047 if useField: 1048 if useInitialData: 1049 form.addInputFieldFor(varname, ldo.hrefSchema, 1050 templateData[varname]) 1051 else: 1052 form.addInputFieldFor(varname, ldo.hrefSchema) 1054 inputData = form.acceptInput() 1056 if not isValid(inputData, hrefSchema): 1057 fatal("Input invalid, link is not usable") 1059 return inputData: 1061 7.2.3. Encoding Data as Strings 1063 This section is straightforward, converting literals to their names 1064 as strings, and converting numbers to strings in the most obvious 1065 manner, and percent-encoding as needed for use in the URI. 1067 for varname in templateData: 1068 value = templateData[varname] 1069 if value is true: 1070 templateData[varname] = "true" 1071 else if value is false: 1072 templateData[varname] = "false" 1073 else if value is null: 1074 templateData[varname] = "null" 1075 else if value is a number: 1076 templateData[varname] = 1077 bestEffortOriginalJsonString(value) 1078 else: 1079 templateData[varname] = rfc3986PercentEncode(value) 1081 In some software environments the original JSON representation of a 1082 number will not be available (there is no way to tell the difference 1083 between 1.0 and 1), so any reasonable representation should be used. 1084 Schema and API authors should bear this in mind, and use other types 1085 (such as string or boolean) if the exact representation is important. 1086 If the number was provide as input in the form of a string, the 1087 string used as input SHOULD be used. 1089 7.3. Providing Access to LDO Keywords 1091 For a given link, an implementation MUST make the values of all 1092 target attribute keywords directly available to the user agent. 1093 Implementations MAY provide additional interfaces for using this 1094 information, as discussed in each keyword's section. 1096 For a given link, an implementation MUST make the value of each input 1097 schema keyword directly available to the user agent. 1099 To encourage encapsulation of the URI Template resolution process, 1100 implementations MAY omit the LDO keywords that are used only to 1101 construct URIs. However, implementations MUST provide access to the 1102 link relation type. 1104 Unrecognized keywords SHOULD be made available to the user agent, and 1105 MUST otherwise be ignored. 1107 7.4. Requests 1109 A hyper-schema implementation SHOULD provide access to all 1110 information needed to construct any valid request to the target 1111 resource. 1113 The LDO can express all information needed to perform any operation 1114 on a link. This section explains what hyper-schema fields a user 1115 agent should examine to build requests from any combination of 1116 instance data and client input. A hyper-schema implementation is not 1117 itself expected to construct and send requests. 1119 Target URI construction rules, including "hrefSchema" for accepting 1120 input, are identical for all possible requests. 1122 Requests that do not carry a body payload do not require additional 1123 keyword support. 1125 Requests that take a target representation as a payload SHOULD use 1126 the "targetSchema" and "targetMediaType" keywords for input 1127 description and payload validation. If a protocol allows an 1128 operation taking a payload that is based on the representation as 1129 modified by a media type (such as a patch media type), then such a 1130 media type SHOULD be indicated through "targetHints" in a protocol- 1131 specific manner. 1133 Requests that take a payload that is not derived from the target 1134 resource's representation SHOULD use the "submissionSchema" and 1135 "submissionMediaType" keywords for input description and payload 1136 validation. Protocols used in hypermedia generally only support one 1137 such non-representation operation per link. 1139 RPC systems that pipe many application operations with arbitrarily 1140 different request structures through a single hypermedia protocol 1141 operation are outside of the scope of a hypermedia format such as 1142 JSON Hyper-Schema. 1144 7.5. Responses 1146 As a hypermedia format, JSON Hyper-Schema is concerned with 1147 describing a resource, including describing its links in sufficient 1148 detail to make all valid requests. It is not concerned with directly 1149 describing all possible responses for those requests. 1151 As in any hypermedia system, responses are expected to be self- 1152 describing. In the context of hyper-schema, this means that each 1153 response MUST link its own hyper-schema(s). While responses that 1154 consist of a representation of the target resource are expected to be 1155 valid against "targetSchema" and "targetMediaType", those keywords 1156 are advisory only and MUST be ignored if contradicted by the response 1157 itself. 1159 Other responses, including error responses, complex redirections, and 1160 processing status representations SHOULD also link to their own 1161 schemas and use appropriate media types (e.g. "application/ 1162 problem+json" [RFC7807] for errors). Certain errors might not link a 1163 schema due to being generated by an intermediary that is not aware of 1164 hyper-schema, rather than by the origin. 1166 User agents are expected to understand protocol status codes and 1167 response media types well enough to handle common situations, and 1168 provide enough information to client applications to handle domain- 1169 specific responses. 1171 Statically mapping all possible responses and their schemas at design 1172 time is outside of the scope of JSON Hyper-Schema, but may be within 1173 the scope of other JSON Schema vocabularies which build on hyper- 1174 schema (see Appendix A.3). 1176 7.6. Streaming Parsers 1178 The requirements around discovering links based on their context, or 1179 using the context of links to identify collections, present unique 1180 challenges when used with streaming parsers. It is not possible to 1181 authoritatively fulfill these requirements without processing the 1182 entire schema and instance documents. 1184 Such implementations MAY choose to return non-authoritative answers 1185 based on data processed to date. When offering this approach, 1186 implementations MUST be clear on the nature of the response, and MUST 1187 offer an option to block and wait until all data is processed and an 1188 authoritative answer can be returned. 1190 8. JSON Hyper-Schema and HTTP 1192 While JSON Hyper-Schema is a hypermedia format and therefore 1193 protocol-independent, it is expected that its most common use will be 1194 in HTTP systems, or systems using protocols such as CoAP that are 1195 explicitly analogous to HTTP. 1197 This section provides guidance on how to use each common HTTP method 1198 with a link, and how collection resources impose additional 1199 constraints on HTTP POST. Additionally, guidance is provided on 1200 hinting at HTTP response header values and describing possible HTTP 1201 request headers that are relevant to the given resource. 1203 Section 13 of the JSON Schema core specification [json-schema] 1204 provides guidance on linking instances in a hypermedia system to 1205 their schemas. This may be done with network-accessible schemas, or 1206 may simply identify schemas which were pre-packaged within the client 1207 application. JSON Hyper-Schema intentionally does not constrain this 1208 mechanism, although it is RECOMMENDED that the techniques outlined in 1209 the core specification be used to whatever extent is possible. 1211 8.1. One Link Per Target and Relation Type 1213 Link Description Objects do not directly indicate what operations, 1214 such as HTTP methods, are supported by the target resource. Instead, 1215 operations should be inferred primarily from link relation types 1216 (Section 6.2.1) and URI schemes. 1218 This means that for each target resource and link relation type pair, 1219 schema authors SHOULD only define a single LDO. While it is possible 1220 to use "allow" with "targetHints" to repeat a relation type and 1221 target pair with different HTTP methods marked as allowed, this is 1222 NOT RECOMMENDED and may not be well-supported by conforming 1223 implementations. 1225 All information necessary to use each HTTP method can be conveyed in 1226 a single LDO as explained in this section. The "allow" field in 1227 "targetHints" is intended simply to hint at which operations are 1228 supported, not to separately define each operation. 1230 Note, however, that a resource may always decline an operation at 1231 runtime, for instance due to authorization failure, or due to other 1232 application state that controls the operation's availability. 1234 8.2. "targetSchema" and HTTP 1236 "targetSchema" describes the resource on the target end of the link, 1237 while "targetMediaType" defines that resource's media type. With 1238 HTTP links, "headerSchema" can also be used to describe valid values 1239 for use in an "Accept" request header, which can support multiple 1240 media types or media ranges. When both ways of indicating the target 1241 media type are present, "targetMediaType" SHOULD indicate the default 1242 representation media type, while the schema for "accept" in 1243 "headerSchema" SHOULD include the default as well as any alternate 1244 media types or media ranges that can be requested. 1246 Since the semantics of many HTTP methods are defined in terms of the 1247 target resource, "targetSchema" is used for requests and/or responses 1248 for several HTTP methods. In particular, "targetSchema" suggests 1249 what a client application can expect for the response to an HTTP GET 1250 or any response for which the "Content-Location" header is equal to 1251 the request URI, and what a client application should send if it 1252 creates or replaces the resource with an HTTP PUT request. These 1253 correlations are defined by RFC 7231, section 4.3.1 - "GET", section 1254 4.3.4 "PUT", and section 3.1.4.2, "Content-Location" [RFC7231]. 1256 Per RFC 5789 [RFC5789], the request structure for an HTTP PATCH is 1257 determined by the combination of "targetSchema" and the request media 1258 type, which is conveyed by the "Accept-Patch" header, which may be 1259 included in "targetHints". Media types that are suitable for PATCH- 1260 ing define a syntax for expressing changes to a document, which can 1261 be applied to the representation described by "targetSchema" to 1262 determine the set of syntactically valid request payloads. Often, 1263 the simplest way to validate a PATCH request is to apply it and 1264 validate the result as a normal representation. 1266 8.3. HTTP POST and the "submission*" keywords 1268 JSON Hyper-Schema allows for resources that process arbitrary data in 1269 addition to or instead of working with the target's representation. 1270 This arbitrary data is described by the "submissionSchema" and 1271 "submissionMediaType" keywords. In the case of HTTP, the POST method 1272 is the only one that handles such data. While there are certain 1273 conventions around using POST with collections, the semantics of a 1274 POST request are defined by the target resource, not HTTP. 1276 In addition to the protocol-neutral "submission*" keywords (see 1277 Section 9.3 for a non-HTTP example), the "Accept-Post" header can be 1278 used to specify the necessary media type, and MAY be advertised via 1279 the "targetHints" field. [[CREF4: What happens if both are used? 1280 Also, "submissionSchema" is a MUST to support, while "targetHints" 1281 are at most a SHOULD. But forbidding the use of "Accept-Post" in 1282 "targetHints" seems incorrect. ]] 1284 Successful responses to POST other than a 201 or a 200 with "Content- 1285 Location" set likewise have no HTTP-defined semantics. As with all 1286 HTTP responses, any representation in the response should link to its 1287 own hyper-schema to indicate how it may be processed. As noted in 1288 Appendix A.2, connecting hyperlinks with all possible operation 1289 responses is not within the scope of JSON Hyper-Schema. 1291 8.4. Optimizing HTTP Discoverability With "targetHints" 1293 [[CREF5: It would be good to also include a section with CoAP 1294 examples.]] 1296 JSON serializations of HTTP response header information SHOULD follow 1297 the guidelines established by the work in progress "A JSON Encoding 1298 for HTTP Header Field Values" [I-D.reschke-http-jfv]. Approaches 1299 shown in that document's examples SHOULD be applied to other 1300 similarly structured headers wherever possible. 1302 Headers for all possible HTTP method responses all share 1303 "headerSchema". In particular, both headers that appear in a HEAD 1304 response and those that appear in an OPTIONS response can appear. No 1305 distinction is made within "headerSchema" as to which method response 1306 contains which header. 1308 It is RECOMMENDED that schema authors provide hints for the values of 1309 the following types of HTTP headers whenever applicable: 1311 o Method allowance 1313 o Method-specific request media types 1315 o Authentication challenges 1317 In general, headers that are likely to have different values at 1318 different times SHOULD NOT be included in "targetHints". 1320 As an example, an Allow header allowing HEAD, GET, and POST would be 1321 shown as follows: 1323 { 1324 "targetHints": { 1325 "allow": ["HEAD", "GET", "POST"] 1326 } 1327 } 1329 Note that this is represented identically whether there is a single- 1330 line Allow header with comma-separated values, multiple Allow headers 1331 on separate lines, each with one value, or any combination of such 1332 arrangements. As is generally true with HTTP headers, comma- 1333 separated values and multiple occurrences of the header are treated 1334 the same way. 1336 8.5. Advertising HTTP Features With "headerSchema" 1338 Schemas SHOULD be written to describe JSON serializations that follow 1339 guidelines established by the work in progress "A JSON Encoding for 1340 HTTP Header Field Values" [I-D.reschke-http-jfv] Approaches shown in 1341 that document's examples SHOULD be applied to other similarly 1342 structured headers wherever possible. 1344 It is RECOMMENDED that schema authors describe the available usage of 1345 the following types of HTTP headers whenever applicable: 1347 o Content negotiation 1349 o Authentication and authorization 1350 o Range requests 1352 o The "Prefer" header 1354 Headers such as cache control and conditional request headers are 1355 generally implemented by intermediaries rather than the resource, and 1356 are therefore not generally useful to describe. While the resource 1357 must supply the information needed to use conditional requests, the 1358 runtime handling of such headers and related responses is not 1359 resource-specific. 1361 8.6. Creating Resources Through Collections 1363 When using HTTP, or a protocol such as CoAP that is explicitly 1364 analogous to HTTP, this is done by POST-ing a representation of the 1365 individual resource to be created to the collection resource. The 1366 process for recognizing collection and item resources is described in 1367 Section 6.2.3. 1369 8.7. Content Negotiation and Schema Evolution 1371 JSON Hyper-Schema facilitates HTTP content negotiation, and allows 1372 for a hybrid of the proactive and reactive strategies. As mentioned 1373 above, a hyper-schema can include a schema for HTTP headers such as 1374 "Accept", "Accept-Charset", "Accept-Language", etc with the 1375 "headerSchema" keyword. A user agent or client application can use 1376 information in this schema, such as an enumerated list of supported 1377 languages, in lieu of making an initial request to start the reactive 1378 negotiation process. 1380 In this way, the proactive content negotiation technique of setting 1381 these headers can be informed by server information about what values 1382 are possible, similar to examining a list of alternatives in reactive 1383 negotiation. 1385 For media types that allow specifying a schema as a media type 1386 parameter, the "Accept" values sent in a request or advertised in 1387 "headerSchema" can include the URI(s) of the schema(s) to which the 1388 negotiated representation is expected to conform. One possible use 1389 for schema parameters in content negotiation is if the resource has 1390 conformed to several different schema versions over time. The client 1391 application can indicate what version(s) it understands in the 1392 "Accept" header in this way. 1394 9. Examples 1396 This section shows how the keywords that construct URIs and JSON 1397 Pointers are used. The results are shown in the format used by the 1398 test suite. [[CREF6: Need to post that and link it, but it should be 1399 pretty self-explanatory to those of you reviewing things at this 1400 stage. ]] 1402 Most other keywords are either straightforward ("title" and 1403 "description"), apply validation to specific sorts of input, 1404 requests, or responses, or have protocol-specific behavior. Examples 1405 demonstrating HTTP usage are available in an Appendix (Section 8). 1407 9.1. Entry Point Links, No Templates 1409 For this example, we will assume an example API with a documented 1410 entry point URI of https://example.com/api, which is an empty JSON 1411 object with a link to a schema. Here, the entry point has no data of 1412 its own and exists only to provide an initial set of links: 1414 GET https://example.com/api HTTP/1.1 1416 200 OK 1417 Content-Type: application/json 1418 Link: ; rel="describedBy" 1419 {} 1421 The linked hyper-schema defines the API's base URI and provides two 1422 links: an "about" link to API documentation, and a "self" link 1423 indicating that this is a schema for the base URI. 1425 { 1426 "$id": "https://schema.example.com/entry", 1427 "$schema": "https://json-schema.org/draft/2019-09/hyper-schema", 1428 "base": "https://example.com/api/", 1429 "links": [ 1430 { 1431 "rel": "self", 1432 "href": "../api", 1433 }, { 1434 "rel": "about", 1435 "href": "docs" 1436 } 1437 ] 1438 } 1439 These are the simplest possible links, with only a relation type and 1440 an "href" with no template variables. They resolve as follows: 1442 The duplication of "api" in both the base and the "../api" href in 1443 the "self" link is due to quirks of the RFC 3986 URI-reference 1444 resolution algorithm. In order for relative URI-references to work 1445 well in general, the base URI needs to include a trailing slash. The 1446 "about" link with its "docs" href shows the common case of relative 1447 references, which is used in the other examples in this document. 1449 However, if an API uses URIs without trailing slashes for its 1450 resources, there is no way to provide a relative reference that just 1451 removes a trailing slash without duplicating the path component above 1452 it. Which makes the case of the entry point resource, which differs 1453 from the base URI only in terms of the trailing slash, somewhat 1454 awkward. 1456 Resource URIs, of course, may have trailing slashes, but this example 1457 is intended to highlight this frequently confusing special case. 1459 [ 1460 { 1461 "contextUri": "https://example.com/api", 1462 "contextPointer": "", 1463 "rel": "self", 1464 "targetUri": "https://example.com/api", 1465 "attachmentPointer": "" 1466 }, 1467 { 1468 "contextUri": "https://example.com/api", 1469 "contextPointer": "", 1470 "rel": "about", 1471 "targetUri": "https://example.com/api/docs", 1472 "attachmentPointer": "" 1473 } 1474 ] 1476 The attachment pointer is the root pointer (the only possibility with 1477 an empty object for the instance). The context URI is the default, 1478 which is the requested document. Since application/json does not 1479 allow for fragments, the context pointer is necessary to fully 1480 describe the context. Its default behavior is to be the same as the 1481 attachment pointer. 1483 9.2. Individually Identified Resources 1485 Let's add "things" to our system, starting with an individual thing: 1487 { 1488 "$id": "https://schema.example.com/thing", 1489 "$schema": "https://json-schema.org/draft/2019-09/hyper-schema", 1490 "base": "https://example.com/api/", 1491 "type": "object", 1492 "required": ["data"], 1493 "properties": { 1494 "id": {"$ref": "#/$defs/id"}, 1495 "data": true 1496 }, 1497 "links": [ 1498 { 1499 "rel": "self", 1500 "href": "things/{id}", 1501 "templateRequired": ["id"], 1502 "targetSchema": {"$ref": "#"} 1503 } 1504 ], 1505 "$defs": { 1506 "id": { 1507 "type": "integer", 1508 "minimum": 1, 1509 "readOnly": true 1510 } 1511 } 1512 } 1514 Our "thing" has a server-assigned id, which is required in order to 1515 construct the "self" link. It also has a "data" field which can be 1516 of any type. The reason for the "$defs" section will be clear in the 1517 next example. 1519 Note that "id" is not required by the validation schema, but is 1520 required by the self link. This makes sense: a "thing" only has a 1521 URI if it has been created, and the server has assigned an id. 1522 However, you can use this schema with an instance containing only the 1523 data field, which allows you to validate "thing" instances that you 1524 are about to create. 1526 Let's add a link to our entry point schema that lets you jump 1527 directly to a particular thing if you can supply it's id as input. 1528 To save space, only the new LDO is shown. Unlike "self" and "about", 1529 there is no IANA-registered relationship about hypothetical things, 1530 so an extension relationship is defined using the "tag:" URI scheme 1531 [RFC4151]: 1533 { 1534 "rel": "tag:rel.example.com,2017:thing", 1535 "href": "things/{id}", 1536 "hrefSchema": { 1537 "required": ["id"], 1538 "properties": { 1539 "id": {"$ref": "thing#/$defs/id"} 1540 } 1541 }, 1542 "targetSchema": {"$ref": "thing#"} 1543 } 1545 The "href" value here is the same, but everything else is different. 1546 Recall that the instance is an empty object, so "id" cannot be 1547 resolved from instance data. Instead it is required as client input. 1548 This LDO could also have used "templateRequired" but with "required" 1549 in "hrefSchema" it is not strictly necessary. Providing 1550 "templateRequired" without marking "id" as required in "hrefSchema" 1551 would lead to errors, as client input is the only possible source for 1552 resolving this link. 1554 9.3. Submitting a Payload and Accepting URI Input 1556 This example covers using the "submission" fields for non- 1557 representation input, as well as using them alongside of resolving 1558 the URI Template with input. Unlike HTML forms, which require either 1559 constructing a URI or sending a payload, but do not allow not both at 1560 once, JSON Hyper-Schema can describe both sorts of input for the same 1561 operation on the same link. 1563 The "submissionSchema" and "submissionMediaType" fields are for 1564 describing payloads that are not representations of the target 1565 resource. When used with "http(s)://" URIs, they generally refer to 1566 a POST request payload, as seen in the appendix on HTTP usage 1567 (Section 8). 1569 In this case, we use a "mailto:" URI, which, per RFC 6068, Section 3" 1570 [RFC6068], does not provide any operation for retrieving a resource. 1571 It can only be used to construct a message for sending. Since there 1572 is no concept of a retrievable, replaceable, or deletable target 1573 resource, "targetSchema" and "targetMediaType" are not used. Non- 1574 representation payloads are described by "submissionSchema" and 1575 "submissionMediaType". 1577 We use "submissionMediaType" to indicate a multipart/alternative 1578 payload format, providing two representations of the same data (HTML 1579 and plain text). Since a multipart/alternative message is an ordered 1580 sequence (the last part is the most preferred alternative), we model 1581 the sequence as an array in "submissionSchema". Since each part is 1582 itself a document with a media type, we model each item in the array 1583 as a string, using "contentMediaType" to indicate the format within 1584 the string. 1586 Note that media types such as multipart/form-data, which associate a 1587 name with each part and are not ordered, should be modeled as JSON 1588 objects rather than arrays. 1590 Note that some lines are wrapped to fit this document's width 1591 restrictions. 1593 { 1594 "$id": "https://schema.example.com/interesting-stuff", 1595 "$schema": "https://json-schema.org/draft/2019-09/hyper-schema", 1596 "required": ["stuffWorthEmailingAbout", "email", "title"], 1597 "properties": { 1598 "title": { 1599 "type": "string" 1600 }, 1601 "stuffWorthEmailingAbout": { 1602 "type": "string" 1603 }, 1604 "email": { 1605 "type": "string", 1606 "format": "email" 1607 }, 1608 "cc": false 1609 }, 1610 "links": [ 1611 { 1612 "rel": "author", 1613 "href": "mailto:{email}?subject={title}{&cc}", 1614 "templateRequired": ["email"], 1615 "hrefSchema": { 1616 "required": ["title"], 1617 "properties": { 1618 "title": { 1619 "type": "string" 1620 }, 1621 "cc": { 1622 "type": "string", 1623 "format": "email" 1624 }, 1625 "email": false 1626 } 1627 }, 1628 "submissionMediaType": 1629 "multipart/alternative; boundary=ab2", 1630 "submissionSchema": { 1631 "type": "array", 1632 "items": [ 1633 { 1634 "type": "string", 1635 "contentMediaType": 1636 "text/plain; charset=utf8" 1637 }, 1638 { 1639 "type": "string", 1640 "contentMediaType": "text/html" 1641 } 1642 ], 1643 "minItems": 2 1644 } 1645 } 1646 ] 1647 } 1649 For the URI parameters, each of the three demonstrates a different 1650 way of resolving the input: 1652 email: This variable's presence in "templateRequired" means that it 1653 must be resolved for the template to be used. Since the "false" 1654 schema assigned to it in "hrefSchema" excludes it from the input 1655 data set, it must be resolved from the instance. 1657 title: The instance field matching this variable is required, and it 1658 is also allowed in the input data. So its instance value is used 1659 to pre-populate the input data set before accepting client input. 1660 The client application can opt to leave the instance value in 1661 place. Since this field is required in "hrefSchema", the client 1662 application cannot delete it (although it could set it to an empty 1663 string). 1665 cc: The "false" schema set for this in the main schema prevents this 1666 field from having an instance value. If it is present at all, it 1667 must come from client input. As it is not required in 1668 "hrefSchema", it may not be used at all. 1670 So, given the following instance retrieved from 1671 "https://example.com/api/stuff": 1673 { 1674 "title": "The Awesome Thing", 1675 "stuffWorthEmailingAbout": "Lots of text here...", 1676 "email": "someone@example.com" 1677 } 1679 We can partially resolve the link as follows, before asking the 1680 client application for input. 1682 { 1683 "contextUri": "https://example.com/api/stuff", 1684 "contextPointer": "", 1685 "rel": "author", 1686 "hrefInputTemplates": [ 1687 "mailto:someone@example.com?subject={title}{&cc}" 1688 ], 1689 "hrefPrepopulatedInput": { 1690 "title": "The Awesome Thing" 1691 }, 1692 "attachmentPointer": "" 1693 } 1695 Notice the "href*" keywords in place of "targetUri". These are three 1696 possible kinds of "targetUri" values covering different sorts of 1697 input. Here are examples of each: 1699 No additional or changed input: "mailto:someone@example.com?subject= 1700 The%20Awesome%20Thing" 1702 Change "title" to "your work": "mailto:someone@example.com?subject=y 1703 our%20work" 1705 Change title and add a "cc" of "other@elsewhere.org": 1706 "mailto:someone@example.com?subject=your%20work&cc=other@elsewhere 1707 .org" 1709 9.4. "anchor", "base" and URI Template Resolution 1711 A link is a typed connection from a context resource to a target 1712 resource. Older link serializations support a "rev" keyword that 1713 takes a link relation type as "rel" does, but reverses the semantics. 1714 This has long been deprecated, so JSON Hyper-Schema does not support 1715 it. Instead, "anchor"'s ability to change the context URI can be 1716 used to reverse the direction of a link. It can also be used to 1717 describe a link between two resources, neither of which is the 1718 current resource. 1720 As an example, there is an IANA-registered "up" relation, but there 1721 is no "down". In an HTTP Link header, you could implement "down" as 1722 ""rev": "up"". 1724 First let's look at how this could be done in HTTP, showing a "self" 1725 link and two semantically identical links, one with "rev": "up" and 1726 the other using "anchor" with "rel": "up" (line wrapped due to 1727 formatting limitations). 1729 GET https://example.com/api/trees/1/nodes/123 HTTP/1.1 1731 200 OK 1732 Content-Type: application/json 1733 Link: ; rel="self" 1734 Link: ; rel="up"; 1735 anchor="https://example.com/api/trees/1/nodes/456" 1736 Link: ; rev="up" 1737 { 1738 "id": 123, 1739 "treeId": 1, 1740 "childIds": [456] 1741 } 1743 Note that the "rel=up" link has a target URI identical to the 1744 "rel=self" link, and sets "anchor" (which identifies the link's 1745 context) to the child's URI. This sort of reversed link is easily 1746 detectable by tools when a "self" link is also present. 1748 The following hyper-schema, applied to the instance in the response 1749 above, would produce the same "self" link and "up" link with 1750 "anchor". It also shows the use of a templated "base" URI, plus both 1751 absolute and relative JSON Pointers in "templatePointers". 1753 { 1754 "$id": "https://schema.example.com/tree-node", 1755 "$schema": "https://json-schema.org/draft/2019-09/hyper-schema", 1756 "base": "trees/{treeId}/", 1757 "properties": { 1758 "id": {"type": "integer"}, 1759 "treeId": {"type": "integer"}, 1760 "childIds": { 1761 "type": "array", 1762 "items": { 1763 "type": "integer", 1764 "links": [ 1765 { 1766 "anchor": "nodes/{thisNodeId}", 1767 "rel": "up", 1768 "href": "nodes/{childId}", 1769 "templatePointers": { 1770 "thisNodeId": "/id", 1771 "childId": "0" 1772 } 1773 } 1774 ] 1775 } 1776 } 1777 }, 1778 "links": [ 1779 { 1780 "rel": "self", 1781 "href": "nodes/{id}" 1782 } 1783 ] 1784 } 1786 The "base" template is evaluated identically for both the target 1787 ("href") and context ("anchor") URIs. 1789 Note the two different sorts of templatePointers used. "thisNodeId" 1790 is mapped to an absolute JSON Pointer, "/id", while "childId" is 1791 mapped to a relative pointer, "0", which indicates the value of the 1792 current item. Absolute JSON Pointers do not support any kind of 1793 wildcarding, so there is no way to specify a concept like "current 1794 item" without a relative JSON Pointer. 1796 9.5. Collections 1798 In many systems, individual resources are grouped into collections. 1799 Those collections also often provide a way to create individual item 1800 resources with server-assigned identifiers. 1802 For this example, we will re-use the individual thing schema as shown 1803 in an earlier section. It is repeated here for convenience, with an 1804 added "collection" link with a "targetSchema" reference pointing to 1805 the collection schema we will introduce next. 1807 { 1808 "$id": "https://schema.example.com/thing", 1809 "$schema": "https://json-schema.org/draft/2019-09/hyper-schema", 1810 "base": "https://example.com/api/", 1811 "type": "object", 1812 "required": ["data"], 1813 "properties": { 1814 "id": {"$ref": "#/$defs/id"}, 1815 "data": true 1816 }, 1817 "links": [ 1818 { 1819 "rel": "self", 1820 "href": "things/{id}", 1821 "templateRequired": ["id"], 1822 "targetSchema": {"$ref": "#"} 1823 }, { 1824 "rel": "collection", 1825 "href": "/things", 1826 "targetSchema": {"$ref": "thing-collection#"}, 1827 "submissionSchema": {"$ref": "#"} 1828 } 1829 ], 1830 "$defs": { 1831 "id": { 1832 "type": "integer", 1833 "minimum": 1, 1834 "readOnly": true 1835 } 1836 } 1837 } 1839 The "collection" link is the same for all items, so there are no URI 1840 Template variables. The "submissionSchema" is that of the item 1841 itself. As described in Section 6.2.3, if a "collection" link 1842 supports a submission mechanism (POST in HTTP) then it MUST implement 1843 item creation semantics. Therefore "submissionSchema" is the schema 1844 for creating a "thing" via this link. 1846 Now we want to describe collections of "thing"s. This schema 1847 describes a collection where each item representation is identical to 1848 the individual "thing" representation. While many collection 1849 representations only include subset of the item representations, this 1850 example uses the entirety to minimize the number of schemas involved. 1851 The actual collection items appear as an array within an object, as 1852 we will add more fields to the object in the next example. 1854 { 1855 "$id": "https://schema.example.com/thing-collection", 1856 "$schema": "https://json-schema.org/draft/2019-09/hyper-schema", 1857 "base": "https://example.com/api/", 1858 "type": "object", 1859 "required": ["elements"], 1860 "properties": { 1861 "elements": { 1862 "type": "array", 1863 "items": { 1864 "allOf": [{"$ref": "thing#"}], 1865 "links": [ 1866 { 1867 "anchorPointer": "", 1868 "rel": "item", 1869 "href": "things/{id}", 1870 "templateRequired": ["id"], 1871 "targetSchema": {"$ref": "thing#"} 1872 } 1873 ] 1874 } 1875 } 1876 }, 1877 "links": [ 1878 { 1879 "rel": "self", 1880 "href": "things", 1881 "targetSchema": {"$ref": "#"}, 1882 "submissionSchema": {"$ref": "thing"} 1883 } 1884 ] 1885 } 1886 Here is a simple two-element collection instance: 1888 { 1889 "elements": [ 1890 {"id": 12345, "data": {}}, 1891 {"id": 67890, "data": {}} 1892 ] 1893 } 1895 Here are all of the links that apply to this instance, including 1896 those that are defined in the referenced individual "thing" schema: 1898 [ 1899 { 1900 "contextUri": "https://example.com/api/things", 1901 "contextPointer": "", 1902 "rel": "self", 1903 "targetUri": "https://example.com/api/things", 1904 "attachmentPointer": "" 1905 }, 1906 { 1907 "contextUri": "https://example.com/api/things", 1908 "contextPointer": "/elements/0", 1909 "rel": "self", 1910 "targetUri": "https://example.com/api/things/12345", 1911 "attachmentPointer": "/elements/0" 1912 }, 1913 { 1914 "contextUri": "https://example.com/api/things", 1915 "contextPointer": "/elements/1", 1916 "rel": "self", 1917 "targetUri": "https://example.com/api/things/67890", 1918 "attachmentPointer": "/elements/1" 1919 }, 1920 { 1921 "contextUri": "https://example.com/api/things", 1922 "contextPointer": "", 1923 "rel": "item", 1924 "targetUri": "https://example.com/api/things/12345", 1925 "attachmentPointer": "/elements/0" 1926 }, 1927 { 1928 "contextUri": "https://example.com/api/things", 1929 "contextPointer": "", 1930 "rel": "item", 1931 "targetUri": "https://example.com/api/things/67890", 1932 "attachmentPointer": "/elements/1" 1933 }, 1934 { 1935 "contextUri": "https://example.com/api/things", 1936 "contextPointer": "/elements/0", 1937 "rel": "collection", 1938 "targetUri": "https://example.com/api/things", 1939 "attachmentPointer": "/elements/0" 1940 }, 1941 { 1942 "contextUri": "https://example.com/api/things", 1943 "contextPointer": "/elements/1", 1944 "rel": "collection", 1945 "targetUri": "https://example.com/api/things", 1946 "attachmentPointer": "/elements/1" 1947 } 1948 ] 1950 In all cases, the context URI is shown for an instance of media type 1951 application/json, which does not support fragments. If the instance 1952 media type was application/instance+json, which supports JSON Pointer 1953 fragments, then the context URIs would contain fragments identical to 1954 the context pointer field. For application/json and other media 1955 types without fragments, it is critically important to consider the 1956 context pointer as well as the context URI. 1958 There are three "self" links, one for the collection, and one for 1959 each item in the "elements" array. The item "self" links are defined 1960 in the individual "thing" schema which is referenced with "$ref". 1961 The three links can be distinguished by their context or attachment 1962 pointers. We will revisit the "submissionSchema" of the collection's 1963 "self" link in Section 9.5.2. 1965 There are two "item" links, one for each item in the "elements" 1966 array. Unlike the "self" links, these are defined only in the 1967 collection schema. Each of them have the same target URI as the 1968 corresponding "self" link that shares the same attachment pointer. 1969 However, each has a different context pointer. The context of the 1970 "self" link is the entry in "elements", while the context of the 1971 "item" link is always the entire collection regardless of the 1972 specific item. 1974 Finally, there are two "collection" links, one for each item in 1975 "elements". In the individual item schema, these produce links with 1976 the item resource as the context. When referenced from the 1977 collection schema, the context is the location in the "elements" 1978 array of the relevant "thing", rather than that "thing"'s own 1979 separate resource URI. 1981 The collection links have identical target URIs as there is only one 1982 relevant collection URI. While calculating both links as part of a 1983 full set of constructed links may not seem useful, when constructing 1984 links on an as-needed basis, this arrangement means that there is a 1985 "collection" link definition close at hand no matter which "elements" 1986 entry you are processing. 1988 9.5.1. Pagination 1990 Here we add pagination to our collection. There is a "meta" section 1991 to hold the information about current, next, and previous pages. 1992 Most of the schema is the same as in the previous section and has 1993 been omitted. Only new fields and new or (in the case of the main 1994 "self" link) changed links are shown in full. 1996 { 1997 "properties": { 1998 "elements": { 1999 ... 2000 }, 2001 "meta": { 2002 "type": "object", 2003 "properties": { 2004 "prev": {"$ref": "#/$defs/pagination"}, 2005 "current": {"$ref": "#/$defs/pagination"}, 2006 "next": {"$ref": "#/$defs/pagination"} 2007 } 2008 } 2009 }, 2010 "links": [ 2011 { 2012 "rel": "self", 2013 "href": "things{?offset,limit}", 2014 "templateRequired": ["offset", "limit"], 2015 "templatePointers": { 2016 "offset": "/meta/current/offset", 2017 "limit": "/meta/current/limit" 2018 }, 2019 "targetSchema": {"$ref": "#"} 2020 }, { 2021 "rel": "prev", 2022 "href": "things{?offset,limit}", 2023 "templateRequired": ["offset", "limit"], 2024 "templatePointers": { 2025 "offset": "/meta/prev/offset", 2026 "limit": "/meta/prev/limit" 2027 }, 2028 "targetSchema": {"$ref": "#"} 2030 }, { 2031 "rel": "next", 2032 "href": "things{?offset,limit}", 2033 "templateRequired": ["offset", "limit"], 2034 "templatePointers": { 2035 "offset": "/meta/next/offset", 2036 "limit": "/meta/next/limit" 2037 }, 2038 "targetSchema": {"$ref": "#"} 2039 } 2040 ], 2041 "$defs": { 2042 "pagination": { 2043 "type": "object", 2044 "properties": { 2045 "offset": { 2046 "type": "integer", 2047 "minimum": 0, 2048 "default": 0 2049 }, 2050 "limit": { 2051 "type": "integer", 2052 "minimum": 1, 2053 "maximum": 100, 2054 "default": 10 2055 } 2056 } 2057 } 2058 } 2059 } 2061 Notice that the "self" link includes the pagination query that 2062 produced the exact representation, rather than being a generic link 2063 to the collection allowing selecting the page via input. 2065 Given this instance: 2067 { 2068 "elements": [ 2069 {"id": 12345, "data": {}}, 2070 {"id": 67890, "data": {}} 2071 ], 2072 "meta": { 2073 "current": { 2074 "offset": 0, 2075 "limit": 2 2076 }, 2077 "next": { 2078 "offset": 3, 2079 "limit": 2 2080 } 2081 } 2082 } 2084 Here are all of the links that apply to this instance that either did 2085 not appear in the previous example or have been changed with 2086 pagination added. 2088 [ 2089 { 2090 "contextUri": "https://example.com/api/things", 2091 "contextPointer": "", 2092 "rel": "self", 2093 "targetUri": 2094 "https://example.com/api/things?offset=0&limit=2", 2095 "attachmentPointer": "" 2096 }, 2097 { 2098 "contextUri": "https://example.com/api/things", 2099 "contextPointer": "", 2100 "rel": "next", 2101 "targetUri": 2102 "https://example.com/api/things?offset=3&limit=2", 2103 "attachmentPointer": "" 2104 } 2105 ] 2107 Note that there is no "prev" link in the output, as we are looking at 2108 the first page. The lack of a "prev" field under "meta", together 2109 with the "prev" link's "templateRequired" values, means that the link 2110 is not usable with this particular instance. 2112 [[CREF7: It's not clear how pagination should work with the link from 2113 the "collection" links in the individual "thing" schema. 2114 Technically, a link from an item to a paginated or filtered 2115 collection should go to a page/filter that contains the item (in this 2116 case the "thing") that is the link context. See GitHub issue #421 2117 for more discussion. ]] 2119 Let's add a link for this collection to the entry point schema 2120 (Section 9.1), including pagination input in order to allow client 2121 applications to jump directly to a specific page. Recall that the 2122 entry point schema consists only of links, therefore we only show the 2123 newly added link: 2125 { 2126 "rel": "tag:rel.example.com,2017:thing-collection", 2127 "href": "/things{?offset,limit}", 2128 "hrefSchema": { 2129 "$ref": "thing-collection#/$defs/pagination" 2130 }, 2131 "submissionSchema": { 2132 "$ref": "thing#" 2133 }, 2134 "targetSchema": { 2135 "$ref": "thing-collection#" 2136 } 2137 } 2139 Now we see the pagination parameters being accepted as input, so we 2140 can jump to any page within the collection. The link relation type 2141 is a custom one as the generic "collection" link can only be used 2142 with an item as its context, not an entry point or other resource. 2144 9.5.2. Creating the First Item 2146 When we do not have any "thing"s, we do not have any resources with a 2147 relevant "collection" link. Therefore we cannot use a "collection" 2148 link's submission keywords to create the first "thing"; hyper-schemas 2149 must be evaluated with respect to an instance. Since the "elements" 2150 array in the collection instance would be empty, it cannot provide us 2151 with a collection link either. 2153 However, our entry point link can take us to the empty collection, 2154 and we can use the presence of "item" links in the hyper-schema to 2155 recognize that it is a collection. Since the context of the "item" 2156 link is the collection, we simply look for a "self" link with the 2157 same context, which we can then treat as collection for the purposes 2158 of a creation operation. 2160 Presumably, our custom link relation type in the entry point schema 2161 was sufficient to ensure that we have found the right collection. A 2162 client application that recognizes that custom link relation type may 2163 know that it can immediately assume that the target is a collection, 2164 but a generic user agent cannot do so. Despite the presence of a 2165 "-collection" suffix in our example, a generic user agent would have 2166 no way of knowing whether that substring indicates a hypermedia 2167 resource collection, or some other sort of collection. 2169 Once we have recognized the "self" link as being for the correct 2170 collection, we can use its "submissionSchema" and/or 2171 "submissionMediaType" keywords to perform an item creation operation. 2172 [[CREF8: This works perfectly if the collection is unfiltered and 2173 unpaginated. However, one should generally POST to a collection that 2174 will contain the created resource, and a "self" link MUST include any 2175 filters, pagination, or other query parameters. Is it still valid to 2176 POST to such a "self" link even if the resulting item would not match 2177 the filter or appear within that page? See GitHub issue #421 for 2178 further discussion. ]] [[CREF9: Draft-04 of Hyper-Schema defined a 2179 "create" link relation that had the schema, rather than the instance, 2180 as its context. This did not fit into the instance-based link model, 2181 and incorrectly used an operation name for a link relation type. 2182 However, defining a more correctly designed link from the schema to 2183 the collection instance may be one possible approach to solving this. 2184 Again, see GitHub issue #421 for more details. ]] 2186 10. Security Considerations 2188 JSON Hyper-Schema defines a vocabulary for JSON Schema core and 2189 concerns all the security considerations listed there. As a link 2190 serialization format, the security considerations of RFC 8288 Web 2191 Linking [RFC8288] also apply, with appropriate adjustments (e.g. 2192 "anchor" as an LDO keyword rather than an HTTP Link header 2193 attribute). 2195 10.1. Target Attributes 2197 As stated in Section 6.5, all LDO keywords describing the target 2198 resource are advisory and MUST NOT be used in place of the 2199 authoritative information supplied by the target resource in response 2200 to an operation. Target resource responses SHOULD indicate their own 2201 hyper-schema, which is authoritative. 2203 If the hyper-schema in the target response matches (by "$id") the 2204 hyper-schema in which the current LDO was found, then the target 2205 attributes MAY be considered authoritative. [[CREF10: Need to add 2206 something about the risks of spoofing by "$id", but given that other 2207 parts of the specification discourage always re-downloading the 2208 linked schema, the risk mitigation options are unclear. ]] 2210 User agents or client applications MUST NOT use the value of 2211 "targetSchema" to aid in the interpretation of the data received in 2212 response to following the link, as this leaves "safe" data open to 2213 re-interpretation. 2215 When choosing how to interpret data, the type information provided by 2216 the server (or inferred from the filename, or any other usual method) 2217 MUST be the only consideration, and the "targetMediaType" property of 2218 the link MUST NOT be used. User agents MAY use this information to 2219 determine how they represent the link or where to display it (for 2220 example hover-text, opening in a new tab). If user agents decide to 2221 pass the link to an external program, they SHOULD first verify that 2222 the data is of a type that would normally be passed to that external 2223 program. 2225 This is to guard against re-interpretation of "safe" data, similar to 2226 the precautions for "targetSchema". 2228 Protocol meta-data values conveyed in "targetHints" MUST NOT be 2229 considered authoritative. Any security considerations defined by the 2230 protocol that may apply based on incorrect assumptions about meta- 2231 data values apply. 2233 Even when no protocol security considerations are directly 2234 applicable, implementations MUST be prepared to handle responses that 2235 do not match the link's "targetHints" values. 2237 10.2. "self" Links 2239 When link relation of "self" is used to denote a full representation 2240 of an object, the user agent SHOULD NOT consider the representation 2241 to be the authoritative representation of the resource denoted by the 2242 target URI if the target URI is not equivalent to or a sub-path of 2243 the URI used to request the resource representation which contains 2244 the target URI with the "self" link. [[CREF11: It is no longer 2245 entirely clear what was intended by the "sub-path" option in this 2246 paragraph. It may have been intended to allow "self" links for 2247 embedded item representations in a collection, which usually have 2248 target URIs that are sub-paths of that collection's URI, to be 2249 considered authoritative. However, this is simply a common design 2250 convention and does not appear to be based in RFC 3986 or any other 2251 guidance on URI usage. See GitHub issue #485 for further discussion. 2252 ]] 2254 11. Acknowledgments 2256 Thanks to Gary Court, Francis Galiegue, Kris Zyp, and Geraint Luff 2257 for their work on the initial drafts of JSON Schema. 2259 Thanks to Jason Desrosiers, Daniel Perrett, Erik Wilde, Ben Hutton, 2260 Evgeny Poberezkin, Brad Bowman, Gowry Sankar, Donald Pipowitch, Dave 2261 Finlay, and Denis Laxalde for their submissions and patches to the 2262 document. 2264 12. References 2266 12.1. Normative References 2268 [json-schema] 2269 Wright, A. and H. Andrews, "JSON Schema: A Media Type for 2270 Describing JSON Documents", draft-handrews-json-schema-02 2271 (work in progress), November 2017. 2273 [json-schema-validation] 2274 Wright, A., Andrews, H., and G. Luff, "JSON Schema 2275 Validation: A Vocabulary for Structural Validation of 2276 JSON", draft-handrews-json-schema-validation-02 (work in 2277 progress), November 2017. 2279 [relative-json-pointer] 2280 Luff, G. and H. Andrews, "Relative JSON Pointers", draft- 2281 handrews-relative-json-pointer-02 (work in progress), 2282 January 2018. 2284 [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate 2285 Requirement Levels", BCP 14, RFC 2119, 2286 DOI 10.17487/RFC2119, March 1997, 2287 . 2289 [RFC3986] Berners-Lee, T., Fielding, R., and L. Masinter, "Uniform 2290 Resource Identifier (URI): Generic Syntax", STD 66, 2291 RFC 3986, DOI 10.17487/RFC3986, January 2005, 2292 . 2294 [RFC4287] Nottingham, M., Ed. and R. Sayre, Ed., "The Atom 2295 Syndication Format", RFC 4287, DOI 10.17487/RFC4287, 2296 December 2005, . 2298 [RFC6570] Gregorio, J., Fielding, R., Hadley, M., Nottingham, M., 2299 and D. Orchard, "URI Template", RFC 6570, 2300 DOI 10.17487/RFC6570, March 2012, 2301 . 2303 [RFC6573] Amundsen, M., "The Item and Collection Link Relations", 2304 RFC 6573, DOI 10.17487/RFC6573, April 2012, 2305 . 2307 [RFC6901] Bryan, P., Ed., Zyp, K., and M. Nottingham, Ed., 2308 "JavaScript Object Notation (JSON) Pointer", RFC 6901, 2309 DOI 10.17487/RFC6901, April 2013, 2310 . 2312 [RFC8288] Nottingham, M., "Web Linking", RFC 8288, 2313 DOI 10.17487/RFC8288, October 2017, 2314 . 2316 12.2. Informative References 2318 [I-D.reschke-http-jfv] 2319 Reschke, J., "A JSON Encoding for HTTP Header Field 2320 Values", draft-reschke-http-jfv-06 (work in progress), 2321 June 2017. 2323 [RFC2046] Freed, N. and N. Borenstein, "Multipurpose Internet Mail 2324 Extensions (MIME) Part Two: Media Types", RFC 2046, 2325 DOI 10.17487/RFC2046, November 1996, 2326 . 2328 [RFC4151] Kindberg, T. and S. Hawke, "The 'tag' URI Scheme", 2329 RFC 4151, DOI 10.17487/RFC4151, October 2005, 2330 . 2332 [RFC5789] Dusseault, L. and J. Snell, "PATCH Method for HTTP", 2333 RFC 5789, DOI 10.17487/RFC5789, March 2010, 2334 . 2336 [RFC6068] Duerst, M., Masinter, L., and J. Zawinski, "The 'mailto' 2337 URI Scheme", RFC 6068, DOI 10.17487/RFC6068, October 2010, 2338 . 2340 [RFC7230] Fielding, R., Ed. and J. Reschke, Ed., "Hypertext Transfer 2341 Protocol (HTTP/1.1): Message Syntax and Routing", 2342 RFC 7230, DOI 10.17487/RFC7230, June 2014, 2343 . 2345 [RFC7231] Fielding, R., Ed. and J. Reschke, Ed., "Hypertext Transfer 2346 Protocol (HTTP/1.1): Semantics and Content", RFC 7231, 2347 DOI 10.17487/RFC7231, June 2014, 2348 . 2350 [RFC7807] Nottingham, M. and E. Wilde, "Problem Details for HTTP 2351 APIs", RFC 7807, DOI 10.17487/RFC7807, March 2016, 2352 . 2354 Appendix A. Using JSON Hyper-Schema in APIs 2356 Hypermedia APIs, which follow the constraints of the REST 2357 architectural style, enable the creation of generic user agents. 2358 Such a user agent has no application-specific knowledge. Rather, it 2359 understands pre-defined media types, URI schemes, protocols, and link 2360 relations, often by recognizing these and coordinating the use of 2361 existing software that implements support for them. Client 2362 applications can then be built on top of such a user agent, focusing 2363 on their own semantics and logic rather than the mechanics of the 2364 interactions. 2366 Hyper-schema is only concerned with one resource and set of 2367 associated links at a time. Just as a web browser works with only 2368 one HTML page at a time, with no concept of whether or how that page 2369 functions as part of a "site", a hyper-schema-aware user agent works 2370 with one resource at a time, without any concept of whether or how 2371 that resource fits into an API. 2373 Therefore, hyper-schema is suitable for use within an API, but is not 2374 suitable for the description of APIs as complete entities in their 2375 own right. There is no way to describe concepts at the API scope, 2376 rather than the resource and link scope, and such descriptions are 2377 outside of the boundaries of JSON Hyper-Schema. 2379 A.1. Resource Evolution With Hyper-Schema 2381 Since a given JSON Hyper-Schema is used with a single resource at a 2382 single point in time, it has no inherent notion of versioning. 2383 However, a given resource can change which schema or schemas it uses 2384 over time, and the URIs of these schemas can be used to indicate 2385 versioning information. When used with a media type that supports 2386 indicating a schema with a media type parameter, these versioned 2387 schema URIs can be used in content negotiation. 2389 A resource can indicate that it is an instance of multiple schemas, 2390 which allows supporting multiple compatible versions simultaneously. 2391 A client application can then make use of the hyper-schema that it 2392 recognizes, and ignore newer or older versions. 2394 A.2. Responses and Errors 2396 Because a hyper-schema represents a single resource at a time, it 2397 does not provide for an enumeration of all possible responses to 2398 protocol operations performed with links. Each response, including 2399 errors, is considered its own (possibly anonymous) resource, and 2400 should identify its own hyper-schema, and optionally use an 2401 appropriate media type such as RFC 7807's "application/problem+json" 2403 [RFC7807], to allow the user agent or client application to interpret 2404 any information that is provided beyond the protocol's own status 2405 reporting. 2407 A.3. Static Analysis of an API's Hyper-Schemas 2409 It is possible to statically analyze a set of hyper-schemas without 2410 instance data in order to generate output such as documentation or 2411 code. However, the full feature set of both validation and hyper- 2412 schema cannot be accessed without runtime instance data. 2414 This is an intentional design choice to provide the maximum runtime 2415 flexibility for hypermedia systems. JSON Schema as a media type 2416 allows for establishing additional vocabularies for static analysis 2417 and content generation, which are not addressed in this 2418 specification. Additionally, individual systems may restrict their 2419 usage to subsets that can be analyzed statically if full design-time 2420 description is a goal. [[CREF12: Vocabularies for API documentation 2421 and other purposes have been proposed, and contributions are welcome 2422 at https://github.com/json-schema-org/json-schema-vocabularies ]] 2424 Appendix B. ChangeLog 2426 [[CREF13: This section to be removed before leaving Internet-Draft 2427 status.]] 2429 draft-handrews-json-schema-hyperschema-02 2431 * Allow multiple values for "rel" 2433 * Clarify that "headerSchema", like "targetHints", should use 2434 array values 2436 * Clarified link behavior with conditional applicator keywords 2437 such as "if" 2439 * Added and clarified various examples 2441 * Avoid accidentally implying that only POST can be used to 2442 create in HTTP 2444 draft-handrews-json-schema-hyperschema-01 2446 * This draft is purely a bug fix with no functional changes 2448 * Fixed erroneous meta-schema URI (draft-07, not draft-07-wip) 2449 * Removed stray "work in progress" language left over from review 2450 period 2452 * Fixed missing trailing "/" in various "base" examples 2454 * Fixed incorrect draft name in changelog (luff-*-00, not -01) 2456 * Update relative pointer ref to handrews-*-01, also purely a bug 2457 fix 2459 draft-handrews-json-schema-hyperschema-00 2461 * Top to bottom reorganization and rewrite 2463 * Group keywords per RFC 8288 context/relation/target/target 2464 attributes 2466 * Additional keyword groups for template resolution and 2467 describing input 2469 * Clarify implementation requirements with a suggested output 2470 format 2472 * Expanded overview to provide context 2474 * Consolidated examples into their own section, illustrate real- 2475 world patterns 2477 * Consolidated HTTP guidance in its own section 2479 * Added a subsection on static analysis of hyper-schemas 2481 * Consolidated security concerns in their own section 2483 * Added an appendix on usage in APIs 2485 * Moved "readOnly" to the validation specification 2487 * Moved "media" to validation as 2488 "contentMediaType"/"contentEncoding" 2490 * Renamed "submissionEncType" to "submissionMediaType" 2492 * Renamed "mediaType" to "targetMediaType" 2494 * Added "anchor" and "anchorPointer" 2496 * Added "templatePointers" and "templateRequired" 2497 * Clarified how "hrefSchema" is used 2499 * Added "targetHints" and "headerSchema" 2501 * Added guidance on "self", "collection" and "item" link usage 2503 * Added "description" as an LDO keyword 2505 * Added "$comment" in LDOs to match the schema keyword 2507 draft-wright-json-schema-hyperschema-01 2509 * Fixed examples 2511 * Added "hrefSchema" for user input to "href" URI Templates 2513 * Removed URI Template pre-processing 2515 * Clarified how links and data submission work 2517 * Clarified how validation keywords apply hyper-schema keywords 2518 and links 2520 * Clarified HTTP use with "targetSchema" 2522 * Renamed "schema" to "submissionSchema" 2524 * Renamed "encType" to "submissionEncType" 2526 * Removed "method" 2528 draft-wright-json-schema-hyperschema-00 2530 * "rel" is now optional 2532 * rel="self" no longer changes URI base 2534 * Added "base" keyword to change instance URI base 2536 * Removed "root" link relation 2538 * Removed "create" link relation 2540 * Removed "full" link relation 2542 * Removed "instances" link relation 2544 * Removed special behavior for "describedBy" link relation 2545 * Removed "pathStart" keyword 2547 * Removed "fragmentResolution" keyword 2549 * Updated references to JSON Pointer, HTML 2551 * Changed behavior of "method" property to align with hypermedia 2552 best current practices 2554 draft-luff-json-hyper-schema-00 2556 * Split from main specification. 2558 Authors' Addresses 2560 Henry Andrews (editor) 2562 EMail: andrews_henry@yahoo.com 2564 Austin Wright (editor) 2566 EMail: aaa@bzfx.net