<?xml version="1.0" encoding="utf-8"?>
<feed xml:lang="en-us" xmlns="http://www.w3.org/2005/Atom"><title>Simon Willison's Weblog: accept</title><link href="http://simonwillison.net/" rel="alternate"/><link href="http://simonwillison.net/tags/accept.atom" rel="self"/><id>http://simonwillison.net/</id><updated>2009-02-06T10:19:55+00:00</updated><author><name>Simon Willison</name></author><entry><title>Pragmatism, purity and JSON content types</title><link href="https://simonwillison.net/2009/Feb/6/json/#atom-tag" rel="alternate"/><published>2009-02-06T10:19:55+00:00</published><updated>2009-02-06T10:19:55+00:00</updated><id>https://simonwillison.net/2009/Feb/6/json/#atom-tag</id><summary type="html">
    &lt;p&gt;I started a conversation about this on Twitter the other day, but Twitter is a horrible place to have an archived discussion so I'm going to try again here.&lt;/p&gt;

&lt;p&gt;If you're producing a JSON API for other people to use (as opposed to an API that's only really meant for your own local Ajax responses), you need to decide which Content-Type to use. The best option is not entirely obvious.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.ietf.org/rfc/rfc4627.txt"&gt;RFC 4672&lt;/a&gt; defines JSON and reserves &lt;code&gt;application/json&lt;/code&gt; as the preferred media type. The problem is that most browsers will prompt you to download the file rather than displaying it inline (as they would for &lt;code&gt;text/plain&lt;/code&gt; or &lt;code&gt;application/javascript&lt;/code&gt;). One of my favourite qualities of REST-style APIs is that they enable exploration and debugging using just a browser - using &lt;code&gt;application/json&lt;/code&gt; throws a big, frustrating road block in the way. There are ways of telling your browser to treat &lt;code&gt;application/json&lt;/code&gt; in the same way as &lt;code&gt;text/plain&lt;/code&gt; but that doesn't really help you if your aim is to create an API that's easy for other developers to use.&lt;/p&gt;

&lt;p&gt;It's also worth mentioning that if you are returning JSONP (with an extra callback function wrapped around the JSON response to enable the dynamic script tag hack) you HAVE to serve as &lt;code&gt;application/javascript&lt;/code&gt; - otherwise the script you are providing won't be executed by the browser. Don't forget to include &lt;code&gt;charset=UTF8&lt;/code&gt; as well (for both types of response).&lt;/p&gt;

&lt;p&gt;So, it's pragmatism v.s. purity. The &lt;em&gt;correct&lt;/em&gt; thing to do is to return &lt;code&gt;application/json&lt;/code&gt;, but doing so makes your API harder for developers to use.&lt;/p&gt;

&lt;p&gt;In a brief, non-comprehensive review of some existing JSON APIs (FriendFeed, Flickr, Google Social Graph etc) I couldn't find any that were using &lt;code&gt;application/json&lt;/code&gt;, presumably for this exact reason.&lt;/p&gt;

&lt;h4&gt;Using the Accept: header&lt;/h4&gt;

&lt;p&gt;The Accept: header is one of my least favourite parts of HTTP. I like to be confident that if I send a URL to someone, they'll get back exactly the same bytes as I did when I retrieved it myself (I distrust language negotiation for the same reason). However, a number of people suggested it on Twitter and it looks like it could be a useful solution to this problem.&lt;/p&gt;

&lt;p&gt;I'm currently considering the following: ONLY use the &lt;code&gt;application/json&lt;/code&gt; Content-Type in reply to requests that include &lt;code&gt;application/json&lt;/code&gt; in their Accept header - essentially allowing clients that care about the correct content type to opt-in to receiving it. Everyone else (browsers included) gets &lt;code&gt;application/javascript&lt;/code&gt;, which is less correct (though not an all-out lie, since JSON is a subset of JavaScript) but solves the usability problem.&lt;/p&gt;

&lt;p&gt;A couple of things worry me about this. Firstly, is this a reasonable thing to use Accept for? Secondly, is there a chance that browsers might add &lt;code&gt;application/json&lt;/code&gt; to their Accept header at some point in the future? Safari currently sends &lt;code&gt;text/xml,application/xml,application/xhtml+xml,text/html; q=0.9,text/plain; q=0.8,image/png,*/*; q=0.5&lt;/code&gt; while Firefox sends &lt;code&gt;text/html,application/xhtml+xml,application/xml; q=0.9,*/*; q=0.8&lt;/code&gt;. Would it be smarter to look for &lt;code&gt;*/*&lt;/code&gt; and serve the incorrect Content-Type to those requests and the correct one to everything else?&lt;/p&gt;

&lt;p&gt;An alternative is to simply allow people to specify "JSON with a browsable Content-Type" as an alternative format option, or to enable a "pretty=1" query string argument which returns the response as &lt;code&gt;text/plain&lt;/code&gt; and potentially pretty prints it as well. I haven't yet decided if this is better than messing around with the Accept header.&lt;/p&gt;

    
        &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/accept"&gt;accept&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/apis"&gt;apis&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/contenttypes"&gt;contenttypes&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/http"&gt;http&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/json"&gt;json&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/pragmatism"&gt;pragmatism&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/purity"&gt;purity&lt;/a&gt;&lt;/p&gt;
    

</summary><category term="accept"/><category term="apis"/><category term="contenttypes"/><category term="http"/><category term="json"/><category term="pragmatism"/><category term="purity"/></entry><entry><title>Versioning REST Web Services</title><link href="https://simonwillison.net/2008/Oct/13/peter/#atom-tag" rel="alternate"/><published>2008-10-13T12:45:13+00:00</published><updated>2008-10-13T12:45:13+00:00</updated><id>https://simonwillison.net/2008/Oct/13/peter/#atom-tag</id><summary type="html">
    
&lt;p&gt;&lt;strong&gt;&lt;a href="http://barelyenough.org/blog/2008/05/versioning-rest-web-services/"&gt;Versioning REST Web Services&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
Peter Williams suggests using a vendor MIME media type in the Accept header to specify a required API version, because embedding the API version in the URL itself leads to a single resource ending up with many different URLs, one for each API version.


    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/accept"&gt;accept&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/contentnegotiation"&gt;contentnegotiation&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/http"&gt;http&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/peter-williams"&gt;peter-williams&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/rest"&gt;rest&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/urls"&gt;urls&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/versioning"&gt;versioning&lt;/a&gt;&lt;/p&gt;



</summary><category term="accept"/><category term="contentnegotiation"/><category term="http"/><category term="peter-williams"/><category term="rest"/><category term="urls"/><category term="versioning"/></entry></feed>