on the web, links use URIs as identifiers, and while in theory each REST service should provide a single URI as an entry point, in practice, the exact concept of an
entry point is hard to nail down. that's because one of the nice things about hypermedia is that for clients, boundaries between
services disappear, and they can simply traverse a web of interlinked resources, blissfully ignoring deployment details.
this is a powerful architectural principle, and even more so in a world where deployment details should be opaque and could change at any time, without risking disrupting clients. cloud and SaaS proponents often focus on how these approaches decouple service provision and service consumption, and REST and in particular its hypermedia constraint can play an important role in this picture.
what this means is the following: URIs as
entry points are a powerful concept, and services should be designed so that ideally, all of their URIs can be entry points. this means that any URI should allow clients to bootstrap themselves, with the first step being understanding what that URI actually identifies, and what interactions are possible.
as a client traversing hypermedia, the process is that i have some state that contains links, i choose the next interaction based on link types (often using link relations or custom link structures), which represent the why (
why should i follow this link?) of a link. the context where i find this link also gives me a clue on how to use the link: the context's media type should tell me not just where links are, but also what to do with them. however, the media type might simply not do this, either because it has not been designed this way, or because the authors chose to not constrain links in any way. if the media type does provide interaction information, however, it may do so at design time, at runtime, or both.
one example for design time interaction information is AtomPub, where the media type defines that when a member URI is found, it may support
DELETE. one example for runtime interaction information is HTML, where the method attribute provides a runtime hint for how to submit form values to the action URI. in both cases, a client finding the URI can use source context information (design time or runtime context) to understand the affordances of the target URI.
if such a URI is shared or bookmarked, this context may get lost, however, and thus a client would be left with the URI alone, wondering how to interact. but HTTP provides a bootstrapping mechanism:
OPTIONS. however, this does not provide the full picture. for example, an
OPTIONS request on an AtomPub member URI may result in the following response header:
Allow: GET, PUT, DELETE
but that would not tell the client what is acceptable as content in
PUT requests. also, different methods might expect different media types.
PATCH, for example, comes with its own
Accept-Patch header field that allows an
OPTIONS response to specify the accepted
PATCH document formats. for
POST, HTTP does not have a built-in header field, but
Accept-Post has been proposed recently. however, we're still left with a patchwork of hard-to-represent information, scattered across HTTP headers, or not being representable in HTTP headers at all.
OPTIONS allows to respond with content, which could contain a much richer and better structured representation of the interaction affordances of a resource.
OPTIONS responses thus can be a very good place to make a REST service truly self-describing. it should provide all of the information that might help a client to start interacting, including rather advanced information such as URI Templates. another good design goal is to make that representation reusable, so that it can be provided as a representation on the URI itself, but also can be embedded in a link (i.e., on the source side of a link). and finally, why not also make this available as documentation of the media type, since we're designing a representation for interaction information?
in such a design, there are four sources where clients might get interaction information:
- media types containing links may define constraints that allow clients to follow links in a certain way (AtomPub).
- media types might provide runtime information allowing clients to decide at runtime how to follow links in a certain way (HTML form submission).
- link target URIs might expose interaction information as a response to
- link target URIs behave in a way so that clients simply interacting with them can learn from them (
Accept-Postin a response to a
step 4 is taken care of by what can be represented in HTTP itself. however, for steps 1-3, it would make sense to use the same model of how link interaction information is represented. because this can be important bootstrapping information for clients, Home Documents for HTTP APIs include link interaction information. the current version has this as an integral part of the home document format itself.
however, thinking through the above scenarios, it seems that it better should be designed standalone, and made reusable. then it can be reused in the home document format, in other media types as well, and it also can be used standalone as a response format for
OPTIONS. currently, two such proposals are under development:
- mark nottingham's link hints take the home document model, and propose it as a separate model for a future version of the home document draft.
- my own link descriptions are similar, but a bit more ambitious, most importantly by adding support for URI templates, and registering a media type so that it can be used standalone. here's a simple "edit" link description example and there's even some primitive XML-to-HTML XSLT.
both drafts are -00 and need some work, and since there is a lot of overlap, they should be combined/merged at some point in time. for the link description work, the next version will make the model more hierarchical, so that it is easier to have "conditional hints" based on HTTP methods (and maybe even media types), representing constraints such as
PUT requests accept
image/png up to a maximum size of 50mb.
finally, the grand plan for all of this is to reuse it in a documentation framework called Sedola, which supports structured access to documentation of media types and other REST concepts (see the example for AtomPub which then is used to generate compiled documentation such as this list of link relations from a variety of specifications), but should also support capturing link information (and some other things that i'll write about another day).
driving link hints/descriptions forward can improve the runtime experience for REST services (both as source-side embedded information, and as target-side self-describing information). it also plays an important role in improving (access to) service documentation. it seems like the idea has popped up in a variety of places already, but i've never seen it pulled together across steps 1-3 presented above. is it a worthwhile effort to design such a reusable link information model? time will tell...