In University of Southampton’s WebTeam Blog Christopher Gutteridge just complained that HTTP content negotiation could do better. And he is right. In a nutshell, content negotiation allows to retrieve different forms, versions or representations of a digital document at the same URI.
Content negotiation is an important part of the Web architecture, but sucks for several reasons. The main problem is: there is no consensus about what defines a format/version/representation etc. and how to refer to selected forms of a digital document. At least for selection by different versions in time, there is a good specification with Memento and
Accept-Datetime header. Content negotiation by language (
Accept-Language) is similar unless you want to query by other aspects of language (slang, readability…), because language tags are clearly defined and precise. But the concept of “content types” (
Accept header, also known as MIME types) is rather fuzzy.
Earlier I wrote about the difficulties to define “publication types” – it’s the same problem: there is no disjoint set of content types, document types, publication types, or formats! Each document and each representation can belong to multiple types and types may overlap. The easiest case, described by Christopher, is a subset relation between two types: for instance every XML document is also a Unicode string (be warned: there is no hierarchy of types, but maybe a Directed Acyclic Graph!). Not even this simple relationship between content types can be handled by HTTP content negotiation.
Anyway, the real reason for writing this post is yet another CPAN module I wrote: Plack::App::unAPI implements unAPI. unAPI is a kind of “poor man’s content negotiation”. Instead of sending additional HTTP headers, you directly select a format with
format=... parameters. In contrast to HTTP Content negotiation, an unAPI server also returns a list of all formats it supports. This is a strong argument for unAPI in my opinion. I also added a method to combine unAPI with HTTP content negotiation.