Common REST Mistakes
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.
-
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.
-
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.
-
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.
-
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.
-
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.
-
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).
-
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.
-
Do not worry about protocol
independence. There exists only one protocol which supports 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.
HTML rendition created using stylesheets by Wendell Piez of Mulberry
Technologies.
[up]|[home]