There’s a really nice RFC out that defines the concept of a Link header. Link headers are like Atom links within documents except they are specified within request or response headers. For example let’s say we wanted to GET a medical image of an MRI. This image might have additional relationships to a front, back, top, bottom up view. A response with link headers might look like this:
HTTP/1.1 200, OK Content-Type: image/jpeg Link: <http:/.../front.jpeg>; rel=front; type="image/jpeg",<http://.../back.jpeg>; rel=back;type="image/jpeg" ...
The jpeg format cannot embed hyperlinks within it so to obtain relationship information, the Link header is used. Other than data formats that don’t support hyperlinks, using the Link header can also be very valuable to intermediaries that don’t care or want to know about the content being exchanged.
Link headers vs. Custom headers
I really like the logical concept of Link headers. The syntax of the header is also solid and fine. The problem I have with it though is that it is non-trivial to parse. Please, please, correct me if I’m wrong, but parsing a Link header, according to the current version of the spec, isn’t as easy as doing a few string.splits or simple regular expressions. This is because ‘;=,’ characters can be embedded within quotes. The ‘;’ can also be embedded within links and media types. Not only this, but to get at a specific link I have to parse all the links defined within the header and create a map, before I can define a specific link.
Granted, its not hard to write a parser for this. It is a micro format. The problem is that HTTP libraries generally do not have native support for this. Not a very big deal, but IMO, one of the big selling point of REST is its low footprint and the ability to leverage existing libraries to make HTTP invocations. I came across this problem when writing a Javascript client.
This made me think about redefining the problem. Instead, isn’t a Custom HTTP header easier to interact with from an API point-of-view? Do clients and servers really need the media type information (or really any other metadata) about the link? Could we instead have a simple custom header?
HTTP/1.1 200, OK Front-link: http/.../front.jpg Back-link: http://.../back.jpg Content-Type: image/jpeg ...
Then its just a matter of hash lookup using existing HTTP library facilities.
The downside of course to all of this is that you lose all the self-description aspects that are provided by Link headers. Specifically the media type (type attribute) as well as IETF registered links vs. custom link relationships referenced via a URL. IMO, this self-description metadata within Link headers also helps to mitigate against namespace clashes where different domains might define the same header names.
Header Templates?
What if the Link header spec defined a template for header names? like Link-{rel}, Link-{rel}-Type, Link-{rel}-Title, etc… Link-{rel}-{attribute} So, my response might look like this instead:
Link-Front: http:/.../frong.jpg Link-Front-Type: image/jpeg Link-Back: http:/.../back.jpeg Link-Back-Type: image/jpeg
To find links published by a resource is just a matter of iterating through and doing a “startsWith(‘Link’)” on the header.
Oct 15, 2009 @ 01:01:20
You are definitely going through many of the thought processes I have been with OCCI!
While I appreciate your concerns about the Link headers I think it’s best we just write some parsers for people to use and possibly try to have them included in user agents. That or try to fix the draft somehow? Remember there could be an arbitrary number of headers so before long you’ll be saying stuff like Link-1-Name: blah and wishing you’d never gone down that path.
My larger concern is about clients being able to manipulate the link headers and for that I’ve proposed following the Set-Cookie example with a Set-Link header. Similarly I have a [Set-]Category header for organising information and [Set-]Attribute for “server side cookies”. This results in a very flexible meta-model that I think may well be aligned with what you’re trying to achieve with REST-*.
Sam
Oct 15, 2009 @ 01:32:28
As for your Link-1-Name concern, why wouldn’t the current Link header draft run into the same problem? I know its very bad form to include logic into key names in general, but I just don’t like the idea of saying to potential REST-* consumers, “You have to download this script to parse link headers”. Anyways, I’ll just leave it alone…
I like the Set idea. As for Set-Link: I’ve also seen LINK and UNLINK methods in older versions of HTTP.
Oct 15, 2009 @ 01:44:53
Yes, and there was a draft that (unsuccessfully) tried to revive them. While it’s possible to create new verbs you want to have a LOT of momentum behind you (think WebDAV) and even then you should expect the wheels to fall off in weird and wonderful ways (think WebDAV).
Hence the Set-* pattern which is fully compatible with today’s infrastructure and has some hope of surviving as a standard (as it doesn’t take over the entire header namespace as setting arbitrary headers – something I started with – would).
Sam
Oct 15, 2009 @ 01:55:41
If you are just trying to solve a parser problem, this isn’t worth it. Moreover your proposed syntax is not extensible since it limits the syntax of link relations to simple words and not URIs.
Oct 15, 2009 @ 02:44:18
I’m going to drop this whole idea entirely, but was thinking of:
Link-Foobar: http://…/barfoo
Link-Definition-Foobar: http:/…/foobar/link/definition
Link-Type-Foobar: image/jpeg
A “Link-Definition-*” wouldn’t be needed for registered links.
In all, i just became annoyed when I wanted to write a simple Ajax demo with the stuff I’m doing and realized I had to learn a bit more javascript than I wanted to which I had already done once for a Java client.
Oct 15, 2009 @ 07:16:33
Once it’s done once it’s done. We’re already making huge gains and we’re not going to be able to optimise away everything.
Oct 16, 2009 @ 18:58:50
+1 Link, Set-Link, or even Link-template
It is costly to peer into content bodies, moreover, content is typically not very loggable, while headers are a no-brainer. The more appropriate and useful stuff in the headers or uri, the better. Link-template is fine, too, provided it keeps the parsing syntax of normal Link.
William Vambenepe — REST in practice for IT and Cloud management (part 3: wrap-up)
Dec 10, 2009 @ 10:16:27