Error Response Body For Atom

I’ve spent the last month deeply entrenched in the intricacies and idiosyncrasies of RFC 5023(The Atom Publishing Protocol) and RFC 4287(The Atom Syndication Format). You could say that we’re pretty intimate right now…but we haven’t yet made it to “third base.” I’m a gentleman, mind you!

I am, of course, talking about the RFCs for the Atom Publishing Protocol and Atom Syndication Format, and, during my study and research as I’ve been designing and architecting a RESTful (Representational State Transfer) API based on AtomPub, I’ve found that, while the AtomPub suggests and describes HTTP status codes to use in return for various behaviors, it does not, in fact, define the format of the response entity. The AtomPub even goes so far as to state in Section 5.5:

Implementers are asked to note that according to the HTTP specification, HTTP 4xx and 5xx response entities SHOULD include a human-readable explanation of the error.

Still, it doesn’t describe the format of that “human-readable explanation.”

This led me to do quite a bit of searching, which turned up some old posts on the atom-syntax mailing list that addressed questions about error responses:

On August 2, 2003, Joe Gregorio wrote in response to someone’s question about error repsponses:

You are right that the specification at this time does not cover error codes. In general the HTTP Status code should be the first line of defense, such as 403 Not Authorized, etc. There are errors that will need more detail than just the status code, and I see three possibilities:

  1. Do nothing. That is, let the server decide the error code and formatting to return it in. For example, when you get a 404 on a web-site you often get an HTML page or a text/plain document. Not my favorite option.

  2. Mandate a text/plain result that describes the problem.

  3. The third option is to define an XML format for describing errors, e.g.

<error>
<title></title>
<description></description>
</error>

A few days later (August 8th), Joe asked the question, “How should errors be handled?” Sam Ruby replied:

Why reinvent?

http://www.w3.org/TR/SOAP/#_Toc478383507

I am often (rightfully) accused of being too obtuse. So let me be explicit in what I am suggesting here. Design a pure REST API. Where there seems to be places where “some invention is required”, see if one can reuse precisely those elements - and only those elements - from SOAP. What you will end up with is a fully REST compliant interface which will enjoy wide tooling support.

My first reaction was, “Well, why the hell would I want to use SOAP? I’m trying to be RESTful here!” However, I don’t think what Sam meant was to follow SOAP verbatim but to, rather, borrow from SOAP in much the same way that the Atom community borrowed the WSSE username token from the OASIS Web Services Security committee and adapted it from a specification for SOAP services to a more RESTful application by passing the data through HTTP headers.

Essentially, the implication was to adapt a SOAP Fault to work in a RESTful way.

Diverging from the Atom format and adapting a SOAP format to fit my needs didn’t sit well with me, unfortunately. Rather, as I thought more and more about it, I realized that the Atom format itself suited my needs just fine. So, I decided to use an Atom Entry document that would list an atom:category element for every error that occurred while attempting to process the request (i.e. data validation errors, etc.) and send this back to the user with XHTML in the atom:content element that a client could use to parse and present a human-readable message to their users.

Ultimately, I was happy, could “rest” easy, and the end result looked a bit something like this. This example represents a potential XML entity body of a 400 Bad Request response resulting from invalid data submitted to the Atom service through POST or PUT.

<?xml version="1.0" encoding="utf-8"?>
<entry xmlns="http://www.w3.org/2005/Atom">
<title>An error has occurred</title>
<id>tag:example.org,2008-02:1.0/errors</id>
<updated>2008-02-20T17:08:33Z</updated>
<author>
<name>Ben Ramsey</name>
</author>
<category term="9311" label="Title field missing" scheme="https://api.example.org/1.0/categories/errors"/>
<category term="9301" label="Author field missing" scheme="https://api.example.org/1.0/categories/errors"/>
<content type="xhtml">
<div xmlns="http://www.w3.org/1999/xhtml">
<p>Please correct the following errors:</p>
<ul>
<li>
<a href="http://developer.example.org/errors/9311">
Title field missing
</a>
</li>
<li>
<a href="http://developer.example.org/errors/9301">
Author field missing
</a>
</li>
</ul>
</div>
</content>
</entry>