« Introductory REST Article | Main | Potential GPS + HUD Innovation Ideas for Boating »

2007.12.16

A real RESTful API for SimpleDB

Amazon is catching a lot of flak over their implementation of a RESTful API for SimpleDB.  Stefan calls it "the shittiest REST API in a long time". Bill says that "Ascribing REST to the SimpleDb API might be down to lack of knowledge or marketecture". 

So what is the fuss about? Take a look at the following sample code from the Amazon SimpleDB developer guide:

https://sdb.amazonaws.com/?Action=PutAttributes
    &DomainName=MyDomain
    &ItemName=Item123
    &Attribute.1.Name=Color&Attribute.1.Value=Blue
    &Attribute.2.Name=Size&Attribute.2.Value=Med
    &Attribute.3.Name=Price&Attribute.3.Value=14.99
    &AWSAccessKeyId=
    &Version=2007-11-07
    &Signature=Dqlp3Sd6ljTUA9Uf6SGtEExwUQE=
    &SignatureVersion=1
    &Timestamp=2007-06-25T15%3A01%3A28-07%3A00

Can you see what the problem is? It's kind of subtle, so I'll give you a hint - what is  up with that "Action=PutAttributes" bit in the URL?

The problem is that in REST you use the HTTP methods GET, PUT, POST, DELETE, HEAD and OPTIONS. In the above example, GET is being used. Now, the interesting thing about the GET method is that according to the HTTP spec (RFC 2616), it is "safe":

GET and HEAD methods SHOULD NOT have the significance of taking an action other than retrieval

In other words, the GET method is what you use for reading things (e.g. queries or looking up items). GET should not be used to update things. Lots of web infrastructure rely on these semantics to do their job. Breaking the contract hurts the web.

So how would you make it RESTful? First, I'd recommend taking a look at Joe Gregorio's excellent advice from 2004 on designing a REST API. Joe suggests asking four questions:

  1. What are the URIs?
  2. What's the format?
  3. What methods are supported?
  4. What status codes should be returned?

So lets map out a strawman SimpleDB REST API using these questions as a guideline.

The URI

In this case, we are updating something in MyDomain which is identified by ItemName.

Resource URI
MyDomain List /mydomains/
MyDomain /mydomains/{item-name}

 

The Format

These days, JSON is a pretty decent format to use as a generic starting place. XML is still fine & dandy, but is a little harder to work with in browser clients. You might want to take a look at Atom as well. In any case, clients can use Content Negotiation to ask for their preferred representation.

A JSON format for a SimpleDB item could look like this:

  {
      "DomainName": "MyDomain",
      "ItemName": "Item123",
      "Timestamp": "2007-06-25T15%3A01%3A28-07%3A00",
      "Attributes": {
"Color": "Blue",
"Size": "Med",
"Price": "14.99”
}
  }

The list of items would look like this:

  [
    {"ItemName": "Item123", "href": "https://sdb.amazonaws.com/mydomains/123"},
    {"ItemName": "Item321", "href": "https://sdb.amazonaws.com/mydomains/321”},
    ...
  ]

Notice that in the list we have indicated the href of each specific item.

The Methods

Mapping the available operations to the MyDomain items/item we get the following:

Resource URI Method Description
MyDomain List /mydomains/ GET Retrieve the list of MyDomain items
    POST Create a new MyDomain item
MyDomain /mydomains/{item-name} GET Retrieve a specific MyDomain iem
    PUT Update a MyDomain item
    DELETE Remove a MyDomain item

 

The Status Codes

Joe recommends that you document the status codes that you expect to return for each operation. Some of the more common ones are:

  • 200 - OK.
  • 201 - Created. When an item is successfully created return a 201 and the response will include a Location: header with the URI of the newly created item resource.
  • 204 - No Content. Used for a successful DELETE.
  • 301 - Moved Permanently.
  • 400 - Bad Request.
  • 410 - Gone.

Note that in HTTP there is the idea of status code fallback. The 2xx series means success, 3xx means a redirection and the 4xx series means a client error. If a client doesn't understand 201 for example, it can still safely assume that the operation was a success.

So there you have it. My version of a RESTful API for SimpleDB. SimpleDB seems like a very cool idea to me. Let's hope they sort this mess out soon.

TrackBack

TrackBack URL for this entry:
http://www.typepad.com/t/trackback/198107/24257580

Listed below are links to weblogs that reference A real RESTful API for SimpleDB:

Comments

Feed You can follow this conversation by subscribing to the comment feed for this post.

Nice, Gavin; take an opportunity for bitching and go and be all constructive. Next thing you know, someone might learn something, and then where would we be? :)

Post a comment

Comments are moderated, and will not appear on this weblog until the author has approved them.

If you have a TypeKey or TypePad account, please Sign In