content-negotiation for humans

Justin Sheehy - Justin Sheehy - February 06, 2009

Simon Willison asked for opinions on how to deliver JSON content properly while also assisting browser-driven exploration and debugging.

Here is a short, simple example of how to use content-negotiation to achieve this.

This is a complete, working webmachine resource with trivial content:


-module(conneg_demo_resource).
-export([init/1, to_json/2, content_types_provided/2]).

-include_lib("webmachine/include/webmachine.hrl").

init([]) -> {ok, x}.

to_json(_,X) -> {"{"key": "value"}n", X}.

content_types_provided(_,X) ->
{[{"application/json", to_json},{"text/plain", to_json}], X}.


A typical request/response, with a tiny bit of header noise trimmed:


$ curl -v http://localhost:8000/js/simonw
> GET /js/simonw HTTP/1.1
> Accept: */*
>
< HTTP/1.1 200 OK
< Vary: Accept
< Server: MochiWeb/1.1 WebMachine/0.20 (There was kicking.)
< Content-Type: application/json
< Content-Length: 17
<
{"key": "value"}


This is what you generally want.  The JSON was delivered with the proper content-type and so on.  Note the presence of the “Vary” header.

However, if the same request is made with a typical browser’s Accept header, like FireFox’s, the result will be different:


> GET /js/simonw HTTP/1.1
> Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5
>
< HTTP/1.1 200 OK
< Vary: Accept
< Server: MochiWeb/1.1 WebMachine/0.20 (There was kicking.)
< Content-Type: text/plain
< Content-Length: 17
<
{"key": "value"}


This time we got the same JSON content, but in text/plain so it will display nicely in a browser window if requested directly.  A Web application loading this content would probably set the Accept header in XHR requests to “Accept: application/json” and get the first response.

This is a straightforward use of content-negotiation that serves a useful purpose and (by using Accept properly and providing the Vary response header) still works well with intermediaries and the rest of the mechanics of the Web.



Categories: Blogs  Justin Sheehy  

Comments

No comments so far, you could be the first.

Add comment

Name:

Email:

URL:

Smileys

Remember my personal information

Notify me of follow-up comments?