RESTful POSTing
In my effort to clean my plate of blog topics, here’s yet another post for this week. I promise to keep this one much shorter…
When discussing RESTful Web Services, I’ve often been known to say that I find it difficult to envision how POST fits in with the REST model. This is because my thinking has been stuck in the past with the old way of doing things. For example, consider the following form that uses the POST method:
<form method="POST" action="create-customer.php">
Name: <input type="text" name="name" /><br />
Address: <input type="text" name="address" /><br />
E-mail: <input type="text" name="email" /><br />
<input type="submit" />
</form>
This form is simple enough. When the user submits it, they send a POST request to create-customer.php to create a new customer in the system with the given name, address, and email values. The problem here is that create-customer.php does not follow the REST model. It does not uniquely identify a resource. Instead, it merely processes data. If I were to call it with a GET request, what would it return? Maybe nothing. This is the RESTless way of doing things.
The RESTful approach requires that all URIs uniquely address a particular resource. With this in mind, an attendee at a recent Atlanta PHP meeting pointed out that the creation of a new customer could be as simple as changing the POST action to /customer. Again, the light bulb in my brain still did not light up because I was thinking about the “old way.”
I suggested that /customer, while it accepts POST data, would still return perhaps the newly created ID of the customer after creation, and this does not represent a unique resource. He pointed out that, when POSTing, you don’t have to get back a unique resource, but if you were to GET it, you should. Thus, when you GET /customer, the response might include an XML document listing all the customers. However, POSTing to it, might create a new customer that gets “inserted” into that listing. Likewise, GETing /customer/1138 returns an XML document of customer data for the customer with ID 1138, but POSTing to it would update the data for that customer.
That’s when the light bulb clicked on, and I realized that it is, in fact, possible to design a RESTful application that makes use of GET, POST, PUT, and DELETE in a very RESTful way.
2 Comments
It's worth reading the Atom Publishing Protocol spec if you're interested in RESTful design.
Don't forget the other HTTP status codes: POSTing a new set of customer data to
/customershould return a201 Createdstatus code along with the location of the new resource.It also sounds like you might still not be clear on what it means to be a "unique resources" -- a resource is anything which can be identified by a URI. It's perfectly acceptable to define
/customeras "the details of the currently-visiting customer", for example. It is conceptually unique, even though it returns a different HTML representation for each viewer. You would probably use theContent-Locationheader to point to a more specific URI, like/customer/{customer_id}. Dereferencing either URI could return the same HTML; what matters is the conceptual difference./blog/posts/1 is "the first post in the blog"
/blog/2002/01/01/frist-psot is "the blog entry posted on 2002-01-01 titled 'frist-psot'".
It's the same content, but two different resources with slightly different semantics.
What really matters is that you think in terms of nouns instead of verbs. "create-customer.php" is wrong because it contains a verb (create), and REST requires that you use only GET, POST, PUT and DELETE. Instead of inventing your own verb, you use POST to append an item to the "collection-of-users" (
/customer) noun. Beyond that it's just a matter of good design versus bad -- using the *right* nouns.You may find the following two sites useful in getting to grips with REST and the concept of valid POSTing to simlar URLs. The "REST dialogues" are quite interesting. Duncan also heavily pushes the ATOM Publishing Protocol as the way to go.
duncan cragg
.. and a couter point from an Ebay developer to some of duncan's points in the REST dialogues
Dan Pritchett
hth