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