|
8 | 8 | <!--<!ENTITY rfc5226 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.5226.xml">-->
|
9 | 9 | <!ENTITY rfc5789 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.5789.xml">
|
10 | 10 | <!ENTITY rfc5988 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.5988.xml">
|
| 11 | +<!ENTITY rfc6068 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.6068.xml"> |
11 | 12 | <!ENTITY rfc6570 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.6570.xml">
|
12 | 13 | <!ENTITY rfc6573 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.6573.xml">
|
13 | 14 | <!ENTITY rfc6901 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.6901.xml">
|
@@ -1366,7 +1367,364 @@ for varname in templateData:
|
1366 | 1367 | </section>
|
1367 | 1368 |
|
1368 | 1369 | <section title="Examples" anchor="examples">
|
1369 |
| - <t><cref>Examples are being added in a subsequent PR.</cref></t> |
| 1370 | + <t> |
| 1371 | + This section shows how the keywords that construct URIs and JSON Pointers |
| 1372 | + are used. The results are shown in the format used by the test suite. |
| 1373 | + <cref> |
| 1374 | + Need to post that and link it, but it should be pretty self-explanatory |
| 1375 | + to those of you reviewing things at this stage. |
| 1376 | + </cref> |
| 1377 | + </t> |
| 1378 | + <t> Most other keywords are either straightforward ("title" and "description"), |
| 1379 | + apply validation to specific sorts of input, requests, or responses, or have |
| 1380 | + protocol-specific behavior. Examples demonstrating HTTP usage are available |
| 1381 | + in <xref target="HTTP">an Appendix</xref>. |
| 1382 | + </t> |
| 1383 | + |
| 1384 | + <section title="Entry point links, no templates"> |
| 1385 | + <t> |
| 1386 | + For this example, we will assume an example API with a documented |
| 1387 | + entry point URI of https://example.com, which is an empty JSON object |
| 1388 | + with a link to a schema. Here, the entry point has no data of its |
| 1389 | + own and exists only to provide an initial set of links: |
| 1390 | + </t> |
| 1391 | + <figure> |
| 1392 | + <artwork> |
| 1393 | +<![CDATA[ |
| 1394 | +GET https://api.example.com HTTP/1.1 |
| 1395 | +
|
| 1396 | +200 OK |
| 1397 | +Content-Type: application/json |
| 1398 | +Link: <https://schema.example.com/entry> rel=describedBy |
| 1399 | +{} |
| 1400 | +]]> |
| 1401 | + </artwork> |
| 1402 | + </figure> |
| 1403 | + <t> |
| 1404 | + The linked hyper-schema defines the API's base URI and provides |
| 1405 | + two links: an "about" link to API documentation, and a "self" |
| 1406 | + link indicating that this is a schema for the base URI. In this |
| 1407 | + case the base URI is also the entry point URI. |
| 1408 | + </t> |
| 1409 | + <figure> |
| 1410 | + <artwork> |
| 1411 | +<![CDATA[ |
| 1412 | +{ |
| 1413 | + "$id": "https://schema.example.com/entry", |
| 1414 | + "$schema": "http://json-schema.org/draft-07-wip/hyper-schema#", |
| 1415 | + "base": "https://api.example.com", |
| 1416 | + "links": [ |
| 1417 | + { |
| 1418 | + "rel": "self", |
| 1419 | + "href": "" |
| 1420 | + }, |
| 1421 | + { |
| 1422 | + "rel": "about", |
| 1423 | + "href": "/docs" |
| 1424 | + } |
| 1425 | + ] |
| 1426 | +}]]> |
| 1427 | + </artwork> |
| 1428 | + </figure> |
| 1429 | + <t> |
| 1430 | + These are the simplest possible links, with only a relation type and |
| 1431 | + an "href" with no template variables. They resolve as follows: |
| 1432 | + </t> |
| 1433 | + <figure> |
| 1434 | + <artwork> |
| 1435 | +<![CDATA[[ |
| 1436 | + { |
| 1437 | + "contextUri": "https://api.example.com", |
| 1438 | + "contextPointer": "", |
| 1439 | + "rel": "self", |
| 1440 | + "targetUri": "https://api.example.com", |
| 1441 | + "attachmentPointer": "" |
| 1442 | + }, |
| 1443 | + { |
| 1444 | + "contextUri": "https://api.example.com", |
| 1445 | + "contextPointer": "", |
| 1446 | + "rel": "about", |
| 1447 | + "targetUri": "https://api.example.com/docs", |
| 1448 | + "attachmentPointer": "" |
| 1449 | + } |
| 1450 | +]]]> |
| 1451 | + </artwork> |
| 1452 | + </figure> |
| 1453 | + <t> |
| 1454 | + The attachment pointer is the root pointer (the only possiblity with |
| 1455 | + an empty object for the instance). The context URI is the default, |
| 1456 | + which is the requested document. Since application/json does not allow |
| 1457 | + for fragments, the context pointer is necessary to fully describe the |
| 1458 | + context. Its default behavior is to be the same as the attachment pointer. |
| 1459 | + </t> |
| 1460 | + </section> |
| 1461 | + <section title="Individually identified resources"> |
| 1462 | + <t> |
| 1463 | + Let's add "things" to our system, starting with an individual thing: |
| 1464 | + </t> |
| 1465 | + <figure> |
| 1466 | + <artwork> |
| 1467 | +<![CDATA[{ |
| 1468 | + "$id": "https://schema.example.com/thing", |
| 1469 | + "$schema": "http://json-schema.org/draft-07-wip/hyper-schema#", |
| 1470 | + "base": "http://api.example.com", |
| 1471 | + "type": "object", |
| 1472 | + "required": ["data"], |
| 1473 | + "properties": { |
| 1474 | + "id": {"$ref": "#/definitions/id"}, |
| 1475 | + "data": true |
| 1476 | + }, |
| 1477 | + "links": [ |
| 1478 | + { |
| 1479 | + "rel": "self", |
| 1480 | + "href": "things/{id}", |
| 1481 | + "templateRequired": ["id"], |
| 1482 | + "targetSchema": {"$ref": "#"} |
| 1483 | + } |
| 1484 | + ], |
| 1485 | + "definitions": { |
| 1486 | + "id": { |
| 1487 | + "type": "integer", |
| 1488 | + "minimum": 1, |
| 1489 | + "readOnly": true |
| 1490 | + } |
| 1491 | + } |
| 1492 | +}]]> |
| 1493 | + </artwork> |
| 1494 | + </figure> |
| 1495 | + <t> |
| 1496 | + Our "thing" has a server-assigned id, which is required in order to |
| 1497 | + construct the "self" link. It also has a "data" field which can be |
| 1498 | + of any type. The reason for the "definitions" section will be clear |
| 1499 | + in the next example. |
| 1500 | + </t> |
| 1501 | + <t> |
| 1502 | + Note that "id" is not required by the validation schema, but is required |
| 1503 | + by the self link. This makes sense: a "thing" only has a URI if it has |
| 1504 | + been created, and the server has assigned an id. However, you can use |
| 1505 | + this schema with an instance containing only the data field, which allows |
| 1506 | + you to validate "thing" instances that you are about to create. |
| 1507 | + </t> |
| 1508 | + <t> |
| 1509 | + Let's add a link to our entry point schema that lets you jump directly |
| 1510 | + to a particular thing if you can supply it's id as input. To save space, |
| 1511 | + only the new LDO is shown. Unlike "self" and "about", there is no |
| 1512 | + IANA-registered relationship about hypothetical things, so an extension |
| 1513 | + relationship is defined using the |
| 1514 | + <xref target="RFC4151">"tag:" URI scheme</xref>: |
| 1515 | + </t> |
| 1516 | + <figure> |
| 1517 | + <artwork> |
| 1518 | +<![CDATA[{ |
| 1519 | + "rel": "tag:rel.example.com,2017:thing", |
| 1520 | + "href": "things/{id}", |
| 1521 | + "hrefSchema": { |
| 1522 | + "required": ["id"], |
| 1523 | + "properties": { |
| 1524 | + "id": {"$ref": "thing#/definitions/id"} |
| 1525 | + } |
| 1526 | + }, |
| 1527 | + "targetSchema": {"$ref": "thing#"} |
| 1528 | +}]]> |
| 1529 | + </artwork> |
| 1530 | + </figure> |
| 1531 | + <t> |
| 1532 | + The "href" value here is the same, but everything else is different. |
| 1533 | + Recall that the instance is an empty object, so "id" cannot be resolved |
| 1534 | + from instance data. Instead it is required as client input. This LDO |
| 1535 | + could also have used "templateRequired" but with "required" in "hrefSchema" |
| 1536 | + it is not strictly necessary. Providing "templateRequired" without marking |
| 1537 | + "id" as required in "hrefSchema" would lead to errors, as client input |
| 1538 | + is the only possible source for resolving this link. |
| 1539 | + </t> |
| 1540 | + </section> |
| 1541 | + <section title="Submitting a payload and accepting URI input"> |
| 1542 | + <t> |
| 1543 | + This example covers using the "submission" fields for non-representation |
| 1544 | + input, as well as using them alongside of resolving the URI Template with |
| 1545 | + input. Unlike HTML forms, which require either constructing a URI or |
| 1546 | + sending a payload, but do not allow not both at once, JSON Hyper-Schema can |
| 1547 | + describe both sorts of input to for the same operation on the same link. |
| 1548 | + </t> |
| 1549 | + <t> |
| 1550 | + The "submissionSchema" and "submissionMediaType" fields are for |
| 1551 | + describing payloads that are not representations of the target resource. |
| 1552 | + When used with "http(s)://" URIs, they generally refer to a POST request |
| 1553 | + payload, as seen in the <xref target="HTTP">appendix on HTTP usage</xref>. |
| 1554 | + </t> |
| 1555 | + <t> |
| 1556 | + In this case, we use a "mailto:" URI, which, per |
| 1557 | + <xref target="RFC6068">RFC 6068, Section 3"</xref>, does not provide any |
| 1558 | + operation for retrieving a resource. It can only be used to construct |
| 1559 | + a message for sending. Since there is no concept of a retrievable, |
| 1560 | + replaceable, or deletable target resource, "targetSchema" and |
| 1561 | + "targetMediaType" are not used. Non-representation payloads are |
| 1562 | + described by "submissionSchema" and "submission MediaType". |
| 1563 | + </t> |
| 1564 | + <t> |
| 1565 | + Therefore, we use "submissionMediaType" to indicate a multipart/alternative |
| 1566 | + payload format, providing two representations of the same data (HTML and |
| 1567 | + plain text). Since a multipart/alternative message is an ordered sequence |
| 1568 | + (the last part is the most preferred alternative), we model the sequence as |
| 1569 | + an array in "submissionSchema". Since each part is itself a document with |
| 1570 | + a media type, we model each item in the array as a string, using |
| 1571 | + "contentMediaType" to indicate the format within the string. |
| 1572 | + </t> |
| 1573 | + <t> |
| 1574 | + Note that media types such as multipart/form-data, which associate a name with |
| 1575 | + each part and are not ordered, should be modeled as JSON objects rather than |
| 1576 | + arrays. |
| 1577 | + </t> |
| 1578 | + <t> |
| 1579 | + For the URI parameters, each of the three demonstrates a different way of |
| 1580 | + resolving the input: |
| 1581 | + <list style="hanging"> |
| 1582 | + <t hangText="email:"> |
| 1583 | + This variable's presence in "templateRequired" means that it must be |
| 1584 | + resolved for the template to be used. Since the "false" schema |
| 1585 | + assigned to it in "hrefSchema" excludes it from the input data set, |
| 1586 | + it must be resolved from the instance. |
| 1587 | + </t> |
| 1588 | + <t hangText="title:"> |
| 1589 | + The instance field matching this variable is required, and it is also |
| 1590 | + allowed in the input data. So its instance value is used to |
| 1591 | + pre-populate the input data set before accepting the client's input. |
| 1592 | + The client can opt to leave the instance value in place. Since |
| 1593 | + this field is required in "hrefSchema", the client cannot delete it |
| 1594 | + (although it could set it to an empty string). |
| 1595 | + </t> |
| 1596 | + <t hangText="cc:"> |
| 1597 | + The "false" schema set for this in the main schema prevents this field |
| 1598 | + from having an instance value. If it is present at all, it must come |
| 1599 | + from client input. As it is not required in "hrefSchema", it may not |
| 1600 | + be used at all. |
| 1601 | + </t> |
| 1602 | + </list> |
| 1603 | + </t> |
| 1604 | + <figure> |
| 1605 | + <preamble> |
| 1606 | + Note that some lines are wrapped to fit this document's width restrictions. |
| 1607 | + </preamble> |
| 1608 | + <artwork> |
| 1609 | +<![CDATA[{ |
| 1610 | + "$id": "https://schema.example.com/interesting-stuff", |
| 1611 | + "$schema": "http://json-schema.org/draft-07-wip/hyper-schema#", |
| 1612 | + "required": ["stuffWorthEmailingAbout", "email", "title"], |
| 1613 | + "properties": { |
| 1614 | + "title": { |
| 1615 | + "type": "string" |
| 1616 | + }, |
| 1617 | + "stuffWorthEmailingAbout": { |
| 1618 | + "type": "string" |
| 1619 | + }, |
| 1620 | + "email": { |
| 1621 | + "type": "string", |
| 1622 | + "format": "email" |
| 1623 | + }, |
| 1624 | + "cc": false |
| 1625 | + }, |
| 1626 | + "links": [ |
| 1627 | + { |
| 1628 | + "rel": "author", |
| 1629 | + "href": "mailto:{email}?subject={title}{&cc}", |
| 1630 | + "templateRequired": ["email"], |
| 1631 | + "hrefSchema": { |
| 1632 | + "required": ["title"], |
| 1633 | + "properties": { |
| 1634 | + "title": { |
| 1635 | + "type": "string" |
| 1636 | + }, |
| 1637 | + "cc": { |
| 1638 | + "type": "string", |
| 1639 | + "format": "email" |
| 1640 | + }, |
| 1641 | + "email": false |
| 1642 | + } |
| 1643 | + } |
| 1644 | + "submissionMediaType": |
| 1645 | + "multipart/alternative; boundary=ab2", |
| 1646 | + "submissionSchema": { |
| 1647 | + "type": "array", |
| 1648 | + "items": [ |
| 1649 | + { |
| 1650 | + "type": "string", |
| 1651 | + "contentMediaType": |
| 1652 | + "text/plain; charset=utf8" |
| 1653 | + }, |
| 1654 | + { |
| 1655 | + "type": "string", |
| 1656 | + "contentMediaType": "text/html" |
| 1657 | + } |
| 1658 | + ], |
| 1659 | + "minItems": 2 |
| 1660 | + } |
| 1661 | + } |
| 1662 | + ] |
| 1663 | +}]]> |
| 1664 | + </artwork> |
| 1665 | + </figure> |
| 1666 | + <t> |
| 1667 | + So, given the following instance retrieved from "https://api.example.com/stuff": |
| 1668 | + </t> |
| 1669 | + <figure> |
| 1670 | + <artwork> |
| 1671 | +<![CDATA[{ |
| 1672 | + "title": "The Awesome Thing", |
| 1673 | + "stuffWorthEmailingAbout": "Lots of text here...", |
| 1674 | + |
| 1675 | +}]]> |
| 1676 | + </artwork> |
| 1677 | + </figure> |
| 1678 | + <t> |
| 1679 | + We can partially resolve the link as follows, before asking the client |
| 1680 | + for input. |
| 1681 | + </t> |
| 1682 | + <figure> |
| 1683 | + <artwork> |
| 1684 | +<![CDATA[{ |
| 1685 | + "contextUri": "https://api.example.com/stuff", |
| 1686 | + "contextPointer": "", |
| 1687 | + "rel": "author", |
| 1688 | + "hrefInputTemplates": [ |
| 1689 | + "mailto:[email protected]?subject={title}{&cc}", |
| 1690 | + ], |
| 1691 | + "hrefPrepopulatedInput": { |
| 1692 | + "title": "The Really Awesome Thing" |
| 1693 | + }, |
| 1694 | + "attachmentPointer": "" |
| 1695 | +}]]> |
| 1696 | + </artwork> |
| 1697 | + </figure> |
| 1698 | + <t> |
| 1699 | + Notice the "href*" keywords in place of "targetUri". These are three |
| 1700 | + possible "targetUri" values covering different sorts of input: |
| 1701 | + <list style="hanging"> |
| 1702 | + <t hangText="No additional or changed input:"> |
| 1703 | + "mailto: [email protected]?subject=The%20Awesome%20Thing" |
| 1704 | + </t> |
| 1705 | + <t hangText='Change "title" to "your work":'> |
| 1706 | + "mailto: [email protected]?subject=your%20work" |
| 1707 | + </t> |
| 1708 | + < t hangText= 'Change title and add a "cc" of "[email protected]":'> |
| 1709 | + "mailto: [email protected]?subject=your%20work &[email protected]" |
| 1710 | + </t> |
| 1711 | + </list> |
| 1712 | + </t> |
| 1713 | + </section> |
| 1714 | + <section title='"anchor" and "base" as URI Templates'> |
| 1715 | + <t><cref> |
| 1716 | + "base" used as a template with both "anchor" and "href" templates. |
| 1717 | + </cref></t> |
| 1718 | + </section> |
| 1719 | + <section title="Collections"> |
| 1720 | + <t><cref> |
| 1721 | + Reciprocal collection/item relations |
| 1722 | + Pagination: fixed links vs jumping to an arbitrary offset |
| 1723 | + Using "anchorPointer" and "templatePointers" |
| 1724 | + Discovering ordered links |
| 1725 | + Multiple self links (for the collection and each item) |
| 1726 | + </cref></t> |
| 1727 | + </section> |
1370 | 1728 | </section>
|
1371 | 1729 |
|
1372 | 1730 | <section title="Security Considerations" anchor="security">
|
@@ -1485,6 +1843,7 @@ for varname in templateData:
|
1485 | 1843 | &rfc4151;
|
1486 | 1844 | &rfc5789;
|
1487 | 1845 | &rfc5988;
|
| 1846 | + &rfc6068; |
1488 | 1847 | &rfc6573;
|
1489 | 1848 | &rfc7230;
|
1490 | 1849 | &rfc7231;
|
|
0 commit comments