Skip to content

Commit 673fb51

Browse files
authored
Merge pull request json-schema-org#434 from handrews/examples
Rough draft of a few examples
2 parents 04d90af + c27a294 commit 673fb51

File tree

1 file changed

+360
-1
lines changed

1 file changed

+360
-1
lines changed

jsonschema-hyperschema.xml

Lines changed: 360 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
<!--<!ENTITY rfc5226 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.5226.xml">-->
99
<!ENTITY rfc5789 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.5789.xml">
1010
<!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">
1112
<!ENTITY rfc6570 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.6570.xml">
1213
<!ENTITY rfc6573 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.6573.xml">
1314
<!ENTITY rfc6901 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.6901.xml">
@@ -1366,7 +1367,364 @@ for varname in templateData:
13661367
</section>
13671368

13681369
<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+
"email": "[email protected]"
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&amp;[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>
13701728
</section>
13711729

13721730
<section title="Security Considerations" anchor="security">
@@ -1485,6 +1843,7 @@ for varname in templateData:
14851843
&rfc4151;
14861844
&rfc5789;
14871845
&rfc5988;
1846+
&rfc6068;
14881847
&rfc6573;
14891848
&rfc7230;
14901849
&rfc7231;

0 commit comments

Comments
 (0)