-
Notifications
You must be signed in to change notification settings - Fork 0
/
draft-nottingham-json-home-00.xml
517 lines (403 loc) · 21.6 KB
/
draft-nottingham-json-home-00.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE rfc SYSTEM "http://xml.resource.org/authoring/rfc2629.dtd" [
<!ENTITY rfc2119 SYSTEM 'http://xml.resource.org/public/rfc/bibxml/reference.RFC.2119.xml'>
<!ENTITY rfc2616 SYSTEM 'http://xml.resource.org/public/rfc/bibxml/reference.RFC.2616.xml'>
<!ENTITY rfc3986 SYSTEM 'http://xml.resource.org/public/rfc/bibxml/reference.RFC.3986.xml'>
<!ENTITY rfc4288 SYSTEM 'http://xml.resource.org/public/rfc/bibxml/reference.RFC.4288.xml'>
<!ENTITY rfc4627 SYSTEM 'http://xml.resource.org/public/rfc/bibxml/reference.RFC.4627.xml'>
<!ENTITY rfc5988 SYSTEM 'http://xml.resource.org/public/rfc/bibxml/reference.RFC.5988.xml'>
<!ENTITY rfc6570 SYSTEM 'http://xml.resource.org/public/rfc/bibxml/reference.RFC.6570.xml'>
]>
<?xml-stylesheet type='text/xsl' href='rfc2629.xslt' ?>
<?rfc toc="yes" ?>
<?rfc tocdepth="3" ?>
<?rfc tocindent="yes" ?>
<?rfc symrefs="yes" ?>
<?rfc sortrefs="yes"?>
<?rfc iprnotified="no" ?>
<?rfc strict="yes" ?>
<?rfc compact="yes" ?>
<?rfc comments="yes" ?>
<?rfc inline="yes" ?>
<rfc ipr="trust200902" docName="draft-nottingham-json-home-00" category="info">
<front>
<title>Home Documents for HTTP APIs</title>
<author initials="M." surname="Nottingham" fullname="Mark Nottingham">
<organization>Rackspace</organization>
<address>
<email>[email protected]</email>
<uri>http://www.mnot.net/</uri>
</address>
</author>
<date year="2012"/>
<abstract>
<t>This document proposes a "home document" format for non-browser
HTTP clients.</t>
</abstract>
</front>
<middle>
<section title="Introduction">
<t>There is an emerging preference for non-browser Web applications
(colloquially, “HTTP APIs”) to use a link-driven approach to their
interactions to assure loose coupling, thereby enabling extensibility
and API evolution.</t>
<t>This is based upon experience with previous APIs which specified
static URI paths (such as
“http://api.example.com/v1.0/widgets/abc123/properties”) have
resulted in brittle, tight coupling between clients and servers. </t>
<t>Sometimes, these APIs are documented by a document format like
<eref target="http://www.w3.org/Submission/wadl/">WADL</eref> that is
used as a “design-time” description; i.e., the URIs and other
information they describe are “baked into” client
implementations.</t>
<t>In contrast, a “follow your nose” API advertises the resources
available to clients using link relations <xref target="RFC5988"/>
and the formats they support using internet media types <xref
target="RFC4288"/>. A client can then decide – at “run time” – which
resources to interact with based upon its capabilities (as described
by link relations), and the server can safely add new resources and
formats without disturbing clients that are not yet aware of
them.</t>
<t>As such, the client needs to be able to discover this information
quickly and efficiently use it to interact with the server. Just as
with a human-targeted “home page” for a site, we can create a “home
document” for a HTTP API (often, at the same URI, found through
server-driven content negotiation) that describes it to non-browser
clients.</t>
<t>Of course, an HTTP API might use any format to do so; however,
there are advantages to having a standard home document format. This
specification suggests one for consideration, using the JSON
format <xref target="RFC4627"/>.</t>
</section>
<section title="Requirements">
<t>The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL
NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in
this document are to be interpreted as described in <xref
target="RFC2119"/>.</t>
</section>
<section anchor="json-home-documents" title="JSON Home Documents">
<t>A JSON Home Document uses the format described in <xref
target="RFC4627"/> and has the media type
“application/json-home”.</t>
<t>Its content consists of a root object with a “resources” property,
whose names are link relation types (as defined by <xref
target="RFC5988"/>), and values are Resource Objects, defined
below.</t>
<t>For example:</t>
<figure><artwork><![CDATA[
GET / HTTP/1.1
Host: example.org
Accept: application/json-home
HTTP/1.1 200 OK
Content-Type: application/json-home
Cache-Control: max-age=3600
Connection: close
{
"resources": {
"http://example.org/rel/widgets": {
"href": "/widgets/"
},
"http://example.org/rel/widget": {
"href-template": "/widgets/{widget_id}",
"href-vars": {
"widget_id": "http://example.org/param/widget"
},
"hints": {
"allow": ["GET", "PUT", "DELETE", "PATCH"],
"representations": ["application/json"],
"accept-patch": ["application/json-patch"],
"accept-post": ["application/xml"],
"accept-ranges": ["bytes"]
}
}
}
}
]]></artwork></figure>
<t>Here, we have a home document that links two a resource,
“/widgets/” with the relation “http://example.org/rel/widgets”, and
also links to one or more with the relation type
“http://example.org/rel/widget” using a URI Template <xref
target="RFC6570"/>.</t>
<t>It also gives several hints about interacting with the latter
“widget” resources, including the HTTP methods usable with them, the
patch formats they accept, and the fact that they support partial
requests <xref target="RFC2616"/> using the “bytes”
range-specifier.</t>
<t>It gives no such hints about the “widgets” resource. This does
not mean that it (for example) doesn’t support any HTTP methods; it
means that the client will need to discover this by interacting with
the resource, and/or examining the documentation for its link
relation type.</t>
</section>
<section anchor="resource-objects" title="Resource Objects">
<t>A Resource Object links to resources of the defined type using one
of two mechanisms; either a direct link (in which case there is
exactly one resource of that relation type associated with the API),
or a templated link, in which case there are zero to many such
resources.</t>
<t>Direct links are indicated with an “href” property, whose value
is a URI <xref target="RFC3986"/>.</t>
<t>Templated links are indicated with an “href-template” property,
whose value is a URI Template <xref target="RFC6570"/>. When
“href-template” is present, the Resource Object MUST have a
“href-vars” property; see “Resolving Templated Links”.</t>
<t>Resource Objects MUST have exactly one of the “href” and
“href-vars” properties.</t>
<t>In both forms, the links that “href” and “href-template” refer to
are URI-references <xref target="RFC3986"/> whose base URI is that
of the JSON Home Document itself.</t>
<t>Resource Objects MAY also have a “hints” property, whose value is
an object that uses named Resource Hints as its properties.</t>
<section anchor="resolving-templates" title="Resolving Templated Links">
<t>A URI can be derived from a Templated Link by treating the
“href-template” value as a Level 3 URI Template <xref
target="RFC6570"/>, using the “href-vars” property to fill the
template.</t>
<t>The “href-vars” property, in turn, is an object that acts as a
mapping between variable names available to the template and
absolute URIs that are used as global identifiers for the
semantics and syntax of those variables.</t>
<t>For example, given the following Resource Object:</t>
<figure><artwork><![CDATA[
"http://example.org/rel/widget": {
"href-template": "/widgets/{widget_id}",
"href-vars": {
"widget_id": "http://example.org/param/widget"
},
"hints": {
"allow": ["GET", "PUT", "DELETE", "PATCH"],
"representations": ["application/json"],
"accept-patch": ["application/json-patch"],
"accept-post": ["application/xml"],
"accept-ranges": ["bytes"]
}
}
]]></artwork></figure>
<t>If you understand that “http://example.org/param/widget” is an
numeric identifier for a widget (perhaps by dereferencing that URL
and reading the documentation), you can then find the resource
corresponding to widget number 12345 at
“http://example.org/widgets/12345” (assuming that the Home
Document is located at “http://example.org/”).</t>
</section>
</section>
<section anchor="resource-hints" title="Resource Hints">
<t>Resource hints allow clients to find relevant information about
interacting with a resource beforehand, as a means of optimising
communications, as well as advertising available behaviours (e.g., to
aid in laying out a user interface for consuming the API).</t>
<t>Hints are just that – they are not a “contract”, and are to only
be taken as advisory. The runtime behaviour of the resource always
overrides hinted information.</t>
<t>For example, a resource might hint that the PUT method is allowed
on all “widget” resources. this means that generally, the user has
the ability to PUT to a particular resource, but a specific resource
may reject a PUT based upon access control or other considerations.
More fine-grained information might be gathered by interacting with
the resource (e.g., via a GET), or by another resource “containing”
it (such as a “widgets” collection).</t>
<t>This specification defines a set of common hints, based upon
information that’s discoverable by directly interacting with
resources. A future draft will explain how to define new hints.</t>
<section anchor="allow" title="allow">
<t>Hints the HTTP methods that the current client will be able to
use to interact with the resource; equivalent to the Allow HTTP
response header.</t>
<t>Content MUST be an array of strings, containing HTTP
methods.</t>
</section>
<section anchor="representations" title="representations">
<t>Hints the representation types that the resource produces and
consumes, using the GET and PUT methods respectively, subject to
the ‘allow’ hint.</t>
<t>Content MUST be an array of strings, containing media
types.</t>
</section>
<section anchor="accept-patch" title="accept-patch">
<t>Hints the PATCH request formats accepted by the resource for
this client; equivalent to the Accept-Patch HTTP response
header.</t>
<t>Content MUST be an array of strings, containing media
types.</t>
</section>
<section anchor="accept-post" title="accept-post">
<t>Hints the POST request formats accepted by the resource for
this client.</t>
<t>Content MUST be an array of strings, containing media
types.</t>
</section>
<section anchor="accept-ranges" title="accept-ranges">
<t>Hints the range-specifiers available to the client for this
resource; equivalent to the Accept-Ranges HTTP response
header.</t>
<t>Content MUST be an array of strings, containing HTTP
range-specifiers. </t>
</section>
</section>
<section anchor="creating" title="Creating and Serving Home Documents">
<t>When making a home document available, there are a few things to
keep in mind:</t>
<t><list style='symbols'>
<t>A home document is best located at a memorable URI, because its
URI will effectively become the URI for the API itself to
clients.</t>
<t>Home documents can be personalised, just as “normal” home pages
can. For example, you might advertise different URIs, and/or
different kinds of link relations, depending on the client’s
identity.</t>
<t>Home documents SHOULD be assigned a freshness lifetime (e.g.,
“Cache-Control: max-age=3600”) so that clients can cache them, to
avoid having to fetch it every time the client interacts with the
service.</t>
<t>Custom link relation types, as well as the URIs for variables,
should lead to documentation for those constructs.</t>
</list></t>
<section anchor="managing-change-in-home-documents" title="Managing Change in Home Documents">
<t>The URIs used in home documents MAY change over time. However,
changing them can cause issues for clients that are relying on
cached home documents containing old links. </t>
<t>To mitigate these risks, servers changing links SHOULD
consider:</t>
<t><list style='symbols'>
<t>Reducing the freshness lifetime of home documents before a
link change, so that clients are less likely to refer to an
“old” document</t>
<t>Assure that they handle requests for the “old” URIs
appropriately; e.g., with a 404 Not Found, or by redirecting the
client to the new URI.</t>
<t>Alternatively, considering the “old” and “new” URIs as
equally valid references for an “overlap” period.</t>
</list></t>
<t>Generally, servers ought not to change URIs without good
cause.</t>
</section>
<section anchor="evolving-and-mixing-apis-with-home-documents" title="Evolving and Mixing APIs with Home Documents">
<t>Using home documents affords the opportunity to change the
“shape” of the API over time, without breaking old clients. </t>
<t>This includes introducing new functions alongside the old ones
– by adding new link relation types with corresponding resource
objects – as well as adding new template variables, media types,
and so on.</t>
<t>It’s important to realise that a home document can serve more
than one “API” at a time; by listing all relevant relation types,
it can effectively “mix” different APIs, allowing clients to work
with different resources as they see fit.</t>
</section>
<section anchor="documenting-apis-that-use-home-documents" title="Documenting APIs that use Home Documents">
<t>Another use case for “static” API description formats like WSDL
and WADL is to generate documentation for the API from them.</t>
<t>An API that uses the home document format correctly won’t have
a need to do so, provided that the link relation types and media
types it uses are well-documented already.</t>
</section>
</section>
<section anchor="consuming-home-documents" title="Consuming Home Documents">
<t>Clients might use home documents in a variety of ways. </t>
<t>In the most common case – actually consuming the API – the client
will scan the Resources Object for the link relation(s) that it is
interested in, and then to interact with the resource(s) referred to.
Resource Hints can be used to optimise communication with the client,
as well as to inform as to the permissible actions (e.g., whether PUT
is likely to be supported).</t>
<t>Note that the home document is a “living” document; it does not
represent a “contract”, but rather is expected to be inspected before
each interaction. In particular, links from the home document MUST
NOT be assumed to be valid beyond the freshness lifetime of the home
document, as per HTTP’s caching model <xref target="RFC2616"/>.</t>
<t>As a result, clients SHOULD cache the home document (as per <xref
target="RFC2616"/>, to avoid fetching it before every interaction
(which would otherwise be required).</t>
<t>Likewise, a client encountering a 404 Not Found on a link SHOULD
obtain a fresh copy of the home document, to assure that it is
up-to-date.</t>
</section>
<section anchor="security-considerations" title="Security Considerations">
<t>TBD</t>
</section>
<section anchor="iana-considerations" title="IANA Considerations">
<t>TBD</t>
</section>
</middle>
<back>
<references title="Normative References">
&rfc2119;
&rfc2616;
&rfc3986;
&rfc4627;
&rfc5988;
&rfc6570;
</references>
<references title="Informative References">
&rfc4288;
</references>
<!-- <section title="Acknowledgements">
<t>Thanks to
for their suggestions and feedback.
</t>
<t>The author takes all responsibility for errors and
omissions.</t>
</section> -->
<section anchor="frequently-asked-questions" title="Frequently Asked Questions">
<section anchor="why-not-microformats" title="Why not Microformats?">
<t>Browser-centric Web applications use HTML as their
representation format of choice. While it is possible to augment
HTML for non-browser clients (using techniques like <eref
target="http://microformats.org/">Microformats</eref> ), a few
issues become evident when doing so:</t>
<t><list style='symbols'>
<t>HTML has a very forgiving syntax. While this is appropriate
for browsers (especially considering that there are many million
HTML authors in the world), it makes for a less-than-precise
language for machines, resulting in both overhead (parsing and
transmission) as well as lack of precision.</t>
<t>HTML is presentation-centric, making it tempting to reformat
it from time to time, to improve the “look and feel” of a page.
However, doing so can cause comparatively brittle non-browser
clients to lose their understanding of the content’s semantics,
unless very careful controls are in place.</t>
</list></t>
<t>Because of this, it’s most practical to define a separate
format, and JSON is easily machine-readable, precise, and has a
better chance of being managed for stability.</t>
</section>
<section anchor="what-about-authentication" title="What about authentication?">
<t>In HTTP, authentication is discoverable by interacting with the
resource (usually, by getting a 401 Unauthorized response status
code, along with one or more challenges). While the home document
could hint it, this isn’t yet done, to avoid possible security
complications.</t>
</section>
<section anchor="what-about-faults-ie-errors" title="What about “Faults” (i.e., errors)?">
<t>In HTTP, errors are conveyed by HTTP status codes. While this
specification could (and even may) allow enumeration of possible
error conditions, there’s a concern that this will encourage
applications to define many such “faults”, leading to tight
coupling between the application and its clients.</t>
<t>So, this is an area of possible future development; if any
such mechanism appears here, it’s likely to be quite
restricted.</t>
</section>
<section title="How Do I find the XML Schema / JSON Schema / etc. for a particular media type?">
<t>That isn’t addressed by home documents. Ultimately, it’s up to
the media type accepted and generated by resources to define and
constrain (or not) their syntax. </t>
</section>
</section>
<section anchor="open-issues" title="Open Issues">
<t>The following is a list of placeholders for open issues.</t>
<t><list style='symbols'>
<t>Refining and extending representation formats - "application/xml",
for example, isn't enough. While a media type for every representation
is one answer, something like 'profile' might be good too.</t>
<t>Object for contact details - do we need an object that describes
who's running the API, etc?</t>
<t>Defining new hints - guidance is needed on minting new hints.
Possibly a registry.</t>
<t>Defining new top-level properties - how new ones are minted,
registry, etc.</t>
<t>Defining new Resource Object properties - how new ones are minted,
registry, etc.</t>
</list></t>
</section>
</back>
</rfc>