Tuesday, June 2, 2009

Common REST Mistakes

Common REST Mistakes( from Paul Prescod)

When designing your first REST system there are a variety of mistakes people often make. I want to summarize them so that you can avoid them. If any are unclear, ask for more information on rest-discuss.
  1. Using HTTP is not enough. You can use HTTP in a Web service without SOAP or XML-RPC and still do the logical equivalent of SOAP or XML-RPC. If you're going to use HTTP wrong you would actually be better off doing it in a standard way! Most of these other points describe ways in which people abuse HTTP.

  2. Do not overuse POST. POST is in some senses the "most flexible" of HTTP's methods. It has a slightly looser definition than the other methods and it supports sending information in and getting information out at the same time. Therefore there is a tendency to want to use POST for everything. In your first REST Web Service, I would say that you should only use POST when you are creating a new URI. Pretend POST means "create new URI as child of the current URI." As you get more sophisticated, you may decide to use POST for other kinds of mutations on a resource. One rule of thumb is to ask yourself whether you are using POST to do something that is really a GET, DELETE or PUT, or could be decomposed into a combination of
    methods.

  3. Do not depend on URI's internal structure. Some people think about REST design in terms of setting up a bunch of URIs. "I'll put purchase orders in /purchases and I'll give them all numbers like /purchases/12132 and customer records will be in
    /customers..." That can be a helpful way to think while you are whiteboarding
    and chatting, but should not be your final public interface to the service. According to Web Architectural principles, most URIs are opaque to client software most of the time. In other words, your public API should not depend on the structure of your URIs. Instead there would typically be a single XML file that points to the components of your service. Those components would have hyperlinks that point to other components and so forth. Then you can introduce people to your service with a single URI and you can distribute the actual components across computers and domains however you want. My rule of thumb is that clients only construct URIs when they are building queries (and thus using query strings). Those queries return references to objects with opaque URIs.

  4. Do not put actions in URIs.
    This follows naturally from the previous point. But a particularly pernicious abuse of URIs is to have query strings like "someuri?action=delete". First, you are using GET to do something unsafe. Second, there is no formal relationship between this "action URI" and the "object" URI. After all your "action=" convention is something specific to your application. REST is about driving as many "application conventions" out of the protocol as possible.
  5. Services are seldom resources. In a REST design, a "stock quote service" is not very
    interesting. In a REST design you would instead have a "stock" resources and a
    service would just be an index of stock resources.

  6. Sessions are irrelevant.
    There should be no need for a client to "login" or "start a connection." HTTP authentication is done automatically on every message. Client applications are consumers of resources, not services. Therefore there is nothing to log in to! Let's say that you are booking a flight on a REST web service. You don't create a new "session" connection to the service. Rather you ask the "itinerary creator object" to create you a new itinerary. You can start filling in the blanks but then get some totally different component elsewhere on the web to fill in some other blanks. There is no session so there is no problem of migrating session state between clients. There is also no issue of "session affinity" in the server (though there are still load balancing issues to continue).

  7. Do not invent proprietary object identifiers. Use URIs. URIs are important because you can always associate information with them in two ways. The simplest way is to put data on a web server so that the URI can be dereferenced in order to get the data. Note that this technique only works with URIs that can be dereferenced so these URIs (http URIs!) are strongly preferred to URN or UUID-based URIs. Another way is to use RDF and other techniques that allow you to project metadata onto a URI
    that may not be under your control. If you use URI syntax with UUIDs or something like that then you get half of the benefit of URIs. You get a standardized syntax but have no standardized dereferencing capability. If you use an HTTP URI then you get the other half of the benefit because you then also have a standardized
    derferencing mechanism.

  8. Do not worry about protocol independence. There exists only one protocol whichsupports the proper resource manipulation semantics. If another one arises in the future, it will be easy to keep your same design and merely support the alternate
    protocol's interface. On the other hand, what people usually mean by "protocol
    independence" is to abandon resource modelling and therefore abandon both REST
    and the Web.
Overall, the thing to keep in mind is that REST is about exposing resources through URIs, not services through messaging interfaces.

No comments: