Often in web application we want to return a different response type depending on the user wish, for example returning an HTML for web browser, returning JSON for Ajax request and XML for Java Client.

Having an unique route returning different response have the advantages to simplify the service design and add some consistency in the URIs. But one may argue that an address represent a resource and thus it should be always the same. It’s were the meaning of the words are important, an URI represent it is not the resource. A resource may have multiple representation, but the content (returned information) is the same.

To distinguish user requested response type the Accept header have to be user. It should not be mixed up with the Content-type header that indicate the entity body (sent user data) type.

Web browser often send multiple value in the Accept header, these values are comma separated. Values may have quality (the q=X parameter where q is a float number between 0 and 1), like:

text/html; q=1, application/json; q=0.7, */*; q=0

Choosing which response type to return must be based on the qualities (we don’t want to return a raw JSON to a human). To do so, Flask have a nice API to find the best MIME type. There is also a snippet to find out how to use it efficiently. With Django Accept header is located in request.META.get('HTTP_ACCEPT') but this is the raw value, if you want to take into account the quality a middleware is available. The Django REST Framework simply use the accepted MIME type order to find the best choice even if the HTTP/1.1 protocol says that it is not the order but the “q” value that is important.

On the client side when using jQuery headers may be provided to $.ajax function with the headers parameters:

$.ajax({url: 'http://foo/bar', headers={Accept: 'application/json'}})

With a GET request a shortcut function is available: $.getJSON, it also parse the returned content. To have the same behaviour with $.ajax the dataType should be set to “json”.

When using cURL, -H parameter have to be used to specify any HTTP header and with httpie, HTTP headers have to be placed after the URI.