REST is not CRUD, and here’s why.

I have encountered several web articles recently which attempt to describe REST verbs (”get”, “put”, “post”, “delete”) in terms of traditional database CRUD (”create”, “read”, “update”, “delete”) operations, and then get stuck trying to map one set to the other.

On the one hand, it’s easy to see why the confusion happens. Both sets have four basic operations, and both sets are concerned with manipulation of stored resources, both have an operation called “delete”, and “read” sounds pretty much like “get”. However, that’s where the similarity stops.

For some recent examples of confusing REST and CRUD, see:

REST and usablity shouldn’t be mixed

Two stage resource oriented web application architectures

Hazem Ahmed Saleh: The rules behind designing a good RESTful service

Even the, otherwise very good, REST Dialogues sometimes fall into this trap.

So, what is the difference?

“Get” and “read” are essentially the same, at least when it comes to fetching raw resource data.

There is a difference in usage, though. In REST a “get” fetches a single resource. CRUD, on the other hand, is often associated with relational databases, which excel in returning sets of results. The common REST approach to multiple results is to return a resource which includes URIs for each resource in the collection (perhaps also with some summary information); the REST client is then free to individually “get” any or all referenced resources which it requires, or if necessary to instead fetch them from a local cache. As an example, consider the loading of images in a web page.

“Delete”, although similar on the surface has some important differences underneath.

In CRUD, the relational heritage often implies the ability to do complex deletes, such as deleting all resources which meet some criteria. In REST the “delete” operation is a simple delete of the resource at a single URI. To delete multiple items using REST typically requires multiple, separate, “delete” requests.

“Put” and “update” can be similar or different depending on interpretation.

The REST “put” operation has strict and well-defined semantics. It ensures that the specified URI has the supplied resource. If the URI is invalid it fails; if the URI contains no resource the supplied resource is placed there; if the URI contains a different resource it is replaced with the supplied resource; if the URI contains the same resource there is no apparent change to the resource at the URI. The CRUD “update” operation, on the other hand is less well-defined. SQL standards do not include a “replace”, “put”, or “insert or update if exists” operation (although many vendor implementations implement such features in a non-standard way). With this in mind, some people interpret the CRUD “update” operation as equivalent to an SQL “update” statement (which only applies if the resource already exists), while others treat it more generally as any form of change which is not a “delete”.

This only leaves “post” and “create”. These are the most different of all.

In REST, “post” is used for any action which results in a resource change or side-effect, and cannot be repeated without the change or side-effect happening again. An SQL “insert” operation would be implemented as a REST “post”, for example, but so would an SQL “update” which increments a value, or the sending of an email. A practical rule of thumb is that a “post” should be simple and quick, leaving the way for future changes using “put” as soon as possible. A CRUD “create” is a quite different thing. “Create” explicitly creates a new resource, and is undefined if that resource already exists.

REST has no direct analogue of “create”. If it is needed (for example) to create and populate a new resource, it is typical to call “post” on some parent resource which results in the return of, or redirect to, a new (empty) URI, and then populate the URI with one or more “put” operations. This approach has the big advantage that the impact of an accidental re-”post” is minimised. In a well designed system, the creating of a new URI could be as low-impact as incrementing an integer, only requiring storage of resource data if/when it is later populated using “put”.

CRUD, on the other hand, has no direct analogue of “post”. A CRUD “create” will probably have side effects, as will some CRUD “update” operations. CRUD is also limited in that it does not include the concept of side-effects outside the resources being managed. There is no way to describe sending an email in terms of CRUD, for example.

In summary, the REST and CRUD are different in many ways, some subtle and some less so.

REST is an approach designed to enable scalable distributed applications to clearly distinguish actions which make no change and thus may be cached or repeated (”get”) from those which make a change but may be casually repeated without problems (”put”, “delete”) from those which should neither be repeated nor cached (”post”). This in turn enables intermediate software (be it in the form of libraries, reusable components, or entirely separate systems) to implement sensible optimisation and error-handling strategies without needing knowledge of the content or relationships of the resources.

CRUD is a description of some generic operations on stored data, with no particular intention of serving as a distribution protocol, and thus little or no planning for the mitigation of problems such as accidental duplicates, time-outs or lost requests.

Attempts, however well-intentioned, to explain one by analogy with the other run a great risk of increasing confusion rather than clearing it. If you are considering using such an analogy, please think twice.

What Makes Good REST?

REST is a very powerful way of thinking about application design, but it can be very hard to really understand. Several people including the originator of REST, Roy Fielding, have written on the subject, and InfoQ has attempted to summarise some of these articles.

InfoQ: What Makes Good REST?

London Java Web User Group: Web apps and REST

This looks interesting. Next Monday (20th October 2008) the London JAVAWUG will be holding a “Birds-of-a-Feather” session on the topic of Web applications and REST web services. Both are subjects near to my heart, so I might try and arrange a trip to “the smoke” that evening.

Anyone else likely to be attending?

JAVAWUG :: Java Web User Group :: London, UK :: Peter Pilgrim, Java Champion : Weblog

How to GET a Cup of Coffee

An intriguing and detailled example of implementing a real-world asynchronous workflow using REST. I’m not sure that I entirely agree with all the choices, but it’s well worth studying to see how capable REST can be.

InfoQ: How to GET a Cup of Coffee

REST Eye for the SOA Guy

Another interesting-looking Qcon presentation for the “to watch” queue. I’m getting a bit bored with the X eye for the Y guy title meme, though.

InfoQ: REST Eye for the SOA Guy

Could we be looking at it all wrong?: Putting REST to rest

This is interesting, in that it is a backlash against REST, which has otherwise been one of the darlings of the software world. I’m not entirely sure if this article is an honest attempt at a refutal, or whether it is merely an attempt to stir up some discussion. But it’s worth reading anyway.

Could we be looking at it all wrong?: Putting REST to rest

Beyond Polling? Consider PubSub, Push and MOM

A typical InfoQ summary of an interesting discussion, this time about the merits and problems of polling REST resources, and how some other approaches might help solve these problems.

InfoQ: Beyond Polling? Consider PubSub, Push and MOM

Testing web services with ActiveResource

When I first saw this it looked great: a ruby REST wrapper which supports a lot of useful test and integration possibilities. However, the deeper I looked, the more disappointed I became. I’m now saddened to believe that this is based on yet another misunderstanding of what REST is.

As far as I can tell, the ActiveResource concept, on which this approach is based, is merely an attempt to impose a constrained CRUD data-model over HTTP. There is no concept of content negotiation - all data is XML according to pre-assumed schemas. There is no support for automatic discovery and use of hrefs between resources. There is even the suggestion that it’s a good idea to casually extend the HTTP protocol with extra custom methods.

All of these are typical problems found in projects which use the name REST without the key bits which make it really work. The end result is just another fragile, application-specific RPC protocol. Sigh.

nutrun » Blog Archive » Testing web services with ActiveResource

So You Say You Want to Kill XML….

Ted Neward has posted a long and detailed discussion of the potential merits and disadvantages of Google’s “protocol buffers” approach compared with XML as a way of offering rich remote APIs.

I learned a lot from this article, and I’m still digesting it, so no snap opinions this time …

Interoperability Happens - So You Say You Want to Kill XML….

And adding to the pot, InfoQ have also written about the same subject:

InfoQ: Google Introduces Binary Encoding Format: Protocol Buffers

The WS-Empire Strikes Back… feebly

I don’t need to say much about this one. Re-implementing a clumsy version of HTTP on top of SOAP seems somewhat crazy.

mnot’s Web log: The WS-Empire Strikes Back… feebly

REST Anti-Patterns

Well worth reading even if you think you understand what REST is all about.

InfoQ: REST Anti-Patterns

Segmentation by Freshness

Martin Fowler’s “bliki” is often an interesting read. This recent article is very thought-provoking, offering a clever way to bridge the gap between fully dynamic and fully-static web pages.

In regular web development, there is a stark choice between marking a web page as fully dynamic (typically by adding a sprinkle of “don’t cache me” headers) and marking it as static and unchanging. Dynamic pages can bypass web-caches to provide up-to-the-minute information, but force the server to handle the load of every request from every user. Static pages gain the speed and scalability advantages from distributed caching but can fall foul of many problems including stale d