EC2 and REST
I have been looking at Amazon EC2. It is a fascinating service. It is quite a thrill to fire up your own linux instances in the cloud the first time. The fun wears off after a bit because linux instances are quite boring on their own. I am sure designing a web application server infrastructure in the cloud will be a lot more fun. So, I started taking baby steps towards that, which involves staring at their HTTP query API.
The EC2 query API, unlike the S3 API is quite un-RESTful. HTTP GET is overloaded and is neither safe nor idempotent. All requests take a list of query parameters, the first parameter is called Action. Most of the other query parameters are arguments to the Action. The remaining are query parameters to deal authentication and non-repudiation. GET is the only HTTP verb used. The three most common actions I used were start, stop and status.
The two primary nouns in the EC2 vocabulary are images and instances. Images are the bits that make up the Xen virtual instance. Instances are runtime instantiations of images. An operation like getStatus() can be intuitively modeled as a GET on an instance resource. However, I got stuck on modeling start and stop.
I then consulted with a REST expert, he suggested that I think of a start as a POST to list of instances and a stop as a DELETE on an instance. An excellent suggestion, although there is a part of me (the dumb part) that feels that this not terribly intuitive. Although it seems to frowned upon, I actually prefer tunneling RPC calls through POSTs. It gives me more latitude to model my rpc’ish calls with a POST and my entity calls with all the verbs. Which leads to me wonder why EC2 did not use POST instead of GET, wouldn’t they have the REST stamp of approval ?
For now, I am sticking with a purist REST interface. Here is my REST table.
| Method | URI | Description |
|---|---|---|
| GET | /user | list all users |
| POST | /user | create a user |
| GET | /user/user1 | retrieve user1 |
| PUT | /user/user1 | update user1 |
| DELETE | /user/user1 | delete user1 |
| GET | /user/{user}/instance | list instances for user |
| POST | /user/{user}/instance | start a new instance on behalf of user |
| GET | /user/{user}/instance/1 | retrieve status of instance 1 |
| DELETE | /user/{user}/instance/1 | stop the instance 1 |
| GET | /user/{user}/image | list all images for the user |
I used ProjectZero to build this out. The code is in an early alpha state in a branch. I checked in the code to https://www.projectzero.org/svn/zero/branches/p_sr_amazonec2. Prior registration on the ProjectZero site is required.
