BT
x Your opinion matters! Please fill in the InfoQ Survey about your reading habits!

Is CRUD Bad for REST?

by Boris Lublinsky on Jul 30, 2009 |

 

Arnon Rotem-Gal-Oz starts his new post "CRUD is bad for REST" by stating that:

On the surface, it seems like a very good fit (both technically and architecturally), however scratch that surface, and you’d see that it isn’t a good fit for either.

Today’s most common implementation of the REST architectural style is based on HTTP and consequently on HTTP verbs namely POST, GET, PUT and DELETE. Common implementers map these verbs into CRUD terms - Create, Read, Update and Delete. A typical mapping is 1 to 1:

  • GET is typically mapped to CRUD Read although GET provides a few features beyond an out-of-the-box SELECT (Read) mapping.
  • DELETE is typically mapped to CRUD Delete
  • PUT is typically mapped to CRUD Update, but with several caveats:
    • PUT requires a complete replacement for the resource while Update can be partial.
    • PUT can be used to Create a resource (when the URI is set by the client)
  • POST is typically mapped to CRUD Create but it supports only the creation of a child resource. POST also can be used to provide partial update to a resource.

In Arnon ’s opinion:

the HTTP verbs are more document oriented than database oriented - while you can update, delete and create new resources the way you do that is not exactly CRUD in the database sense of the word - at least when it comes to using the HTTP verbs.

But the biggest reason why CRUD is not an appropriate paradigm for REST is an architectural one. In the heart of REST is the implementation of the protocol state machine using hypermedia. Arnon quotes Tim Ewald:

... Here's what I came to understand. Every communication protocol has a state machine. For some protocols they are very simple, for others they are more complex. When you implement a protocol via RPC, you build methods that modify the state of the communication. That state is maintained as a black box at the endpoint. Because the protocol state is hidden, it is easy to get things wrong. For instance, you might call Process before calling Init. People have been looking for ways to avoid these problems by annotating interface type information for a long time, but I'm not aware of any mainstream solutions. The fact that the state of the protocol is encapsulated behind method invocations that modify that state in non-obvious ways also makes versioning interesting.

The essence of REST is to make the states of the protocol explicit and addressable by URIs. The current state of the protocol state machine is represented by the URI you just operated on and the state representation you retrieved. You change state by operating on the URI of the state you're moving to, making that your new state. A state's representation includes the links (arcs in the graph) to the other states that you can move to from the current state. This is exactly how browser based apps work, and there is no reason that your app's protocol can't work that way too. (The ATOM Publishing protocol is the canonical example, though its easy to think that its about entities, not a state machine.)

Following John Evdemon’s article, explaining why CRUDy services is an SOA anti pattern, Arnon explains the disadvantages of CRUD REST:

  • It circumvents the whole idea about "Services" - there's no business logic.
  • It is exposing internal database structure or data rather than a thought-out contract.
  • It encourages bypassing real services and going straight to their data.
  • It creates a blob service (the data source).
  • It encourages minuscule demi-serices (the multiple "interfaces" of said blob) that disregard few of the fallacies of distributed computing.
  • It is just client-server in sheep's clothing.

Arnon ends his post by reemphasizing that just adopting standards like HTTP, XML, JSON (although might be useful) does not constitute REST - adopting the REST architecture does.

This post is an important remainder that REST, similar to SOA, is not a set of standards and popular APIs, but rather an architectural paradigm, which needs to be understood and followed.

Hello stranger!

You need to Register an InfoQ account or or login to post comments. But there's so much more behind being registered.

Get the most out of the InfoQ experience.

Tell us what you think

Allowed html: a,b,br,blockquote,i,li,pre,u,ul,p

Email me replies to any of my messages in this thread

First thing first. by Francois Ward

First thing: because we convince people that REST is more than CRUD, we need to convince them that REST isn't "using query strings and urls for everything"

I regularly have people who think as soon as you use POST, its not REST anymore, and that using GET for everything (insert, update, you name it) is the foundation of REST. I'd dare say its a misconception more common than any other...

I respectfully disagree with the title of this blog post. by Bediako George

Although the writer makes many valid points, I disagree with the conclusion as framed in the title. CRUD is not bad for REST. CRUD just represents a small uniform interface which in itself is a single implementation of just one of the four tenets of REST (i) abstract application state into resources, (ii) have uniform identifiers for these resources, (iii) constrain the set of operations allowed on these resources to a finite (preferably small) set of well defined functions, and finally (iv) implement these within a stateless client server protocol.

To say that CRUD is bad is like saying (iii) is not good for REST which in my mind represents a contradiction.

Perhaps a better title would have been "REST. It is so much more than plain CRUD!"?

Re: I respectfully disagree with the title of this blog post. by Boris Lublinsky

Respect is noted and...
I completely agree with you

Re: First thing first. by Boris Lublinsky

I think that this is because most of the people think that REST is about accessing resources from the browser and if you think that cross domain GRT is hard, try to go for cross domain POST. Especially if it returns data.
I think that this is where one of the root causes of a problem - many see REST as a mechanism to support Ajax

Versioning in REST? by Jean-Jacques Dubray

>> Because the protocol state is hidden, it is easy to get things wrong.
Collaboration (and Choreography) definitions have been around for nearly 10 years. OASIS ebBP and ebXML BPSS before that had a "state alignment protocol" that ensure that each party in collaboration has an exact understanding of the collaboration state and message exchanges can be validated against the collaboration definition -automatically.

>> The fact that the state of the protocol is encapsulated behind method invocations that modify
>> that state in non-obvious ways also makes versioning interesting.
Could anyone explain how versioning works in REST? that would be very interesting. Just a small detail... (hint, padding a date in a URI syntax is not a valid answer).

People use CRUD (and 99% of the people that will claim they use REST, will CRUD) simply because it takes less time to get something running. It is not until someone asks the question, why is my (siloed) application so hard to maintain these days? or Why do I have to write this (consumer-side) code for the 20th time? that people start realizing that CRUD was not the right choice. By then it is too late and the industry spends the following 10 years building a CRUDless set of protocols, until some smart guy comes around finds a new way to make CRUD cool again, swearing that these CRUDless protocols induce some kind of instant-death when used.

In about 50 years, people will finally understand that software can indeed be constructed by assembling a series of software components that interact with each other via well defined bi-directional interfaces, with a correct eventing mechanism and CRUD will never be used again.

Re: I respectfully disagree with the title of this blog post. by Christopher Atkins

Likewise I disagree with your assessment of the crux of the argument. The term CRUD is not some facile notion of an informal protocol of four primitive methods; that's a straw man. CRUD carries with it a legacy of relational database semantics. I would say CRUD is orthogonal to REST in the same way that object semantics are orthogonal to service semantics in SOA. Indeed creating CRUD protocols and calling it REST is akin to creating RPC semantics in your service and calling it SOA.



As you point out, the Resource is an abstraction to represent application state. But, you fail to mention perhaps the most important principle of REST, hypertext as the engine of application state. Perhaps that is because, armed with CRUD semantics, you don't need to worry about the hypertext representation of your resources. There is no state machine to convey when all you are doing is CRUD.



The original point, that CRUD is bad for REST, is a true statement about the architectural style called REST insofar as the converse is also true. REST is bad for CRUD. If an application does not need to expose a state machine in a clear, unambiguous, canonical way, then why attempt to adopt REST?



REST is often conflated with the choice of exposing an API using HTTP and an informal protocol rather than the WS-*. Arnon's original blog post compelled me to explore the topic further in my own post, Three Common Fallacies Concerning REST.

Re: I respectfully disagree with the title of this blog post. by Boris Lublinsky

Christopher, we are on the same side.

What you are saying is exactly Arnon's point.
REST != CRUD
They are very different. Unfortunately many practitioners do not share this opinion and try to use REST as CRUD over the Internet

Arnon's article (and my post) are about why this is wrong

Re: I respectfully disagree with the title of this blog post. by Christopher Atkins

Forgive me, but my post was in response to Bediako George. I am not sure I understand how you can agree with both of us. Nevertheless I appreciate your cogent article. It is an important topic.

Re: I respectfully disagree with the title of this blog post. by William Martinez

Pardon me, I think you are all referring to different things!



I agree with Christopher, and I think Bediako as a point, but is not as correct.



1. CRUD is a database semantic oriented set of operations. It is not just the operations, but a whole metaphor that is related specifically to record management.



2. Point iii from REST is an architectural constrain. The idea of this constrain is to make operation of the architecture simple and universal enough. It does not say ANY set of operations will fit.



3. The article states two things: First that the set of operations that is normally used are the HTTP ones, and those are mapped to CRUD breaking the semantics, second that CRUD semantics are not a good set for applications that want to adopt REST as their style.



4. Christopher makes a really good point about how that mapping into CRUD, helps developers to circumvent the hypermedia metaphor by using the data record one. Many applications do not fit into REST, and it is a headache to make them fit, since they need to change the database semantics into distributed hypermedia semantics, just to earn the REST tag! I called that "Wagging the Dog" in one of my blog posts. That demonstrates that developers do not actually grasp what is REST about. They just keep using the same ideas with tools made for other things, they lack the paradigm shift.


William Martinez Pomares.
Architect's Thoughts

PUT does not imply complete replacement by Andy Dent

"PUT requires a complete replacement for the resource while Update can be partial."




No, the situation is one of intense debate as you will find if you Google a set of words like (rest put partial update).



If you just implement partial updates by sending back only a portion of the content, does that imply deletion of the other parts? Personally, I have no problem with the use of XML content and an empty element providing deletion, an occupied element being a replace, in a PUT.

CRUD does not imply direct data access by Andy Dent

The entire list of why CRUD implies direct data access is just wrong, especially:

It is exposing internal database structure or data rather than a thought-out contract.
It encourages bypassing real services and going straight to their data

CRUD is a User Conceptual Pattern about updating a domain object. How that is implemented in your system is up to you and assuming that a CRUD pattern is one-one mapped to database items is just one possible, very simple architecture.

It circumvents the whole idea about "Services" - there's no business logic.

This is not so much about CRUD as about the idea of REST in general. If you don't have simple, imperative command requests then you have to invert thinking a bit, eg: Post a batch becomes get the results of posting a batch.

Interestingly, this switch to a more declarative style maps much better to a concurrent world - it makes no assumptions about currrent state but just asks for the result, which may already have been produced as a processing step.

Saying this is something to do with CRUD is raising the straw man that use of CRUD in a REST system implies that all interfaces in that REST system need to be CRUD.

CRUD not only good, but the only consistent way to build REST over HTTP by Dhananjay Nene

Crud is actually pretty helpful by andrej koelewijn

I think CRUD is actually pretty helpful. Working with large sets of data through an rpc mechanism is pretty hard, and mapping crud to the soa world actually helps people remember the power of sql queries. There is no easier way to find data in large sets of data than using queries. Handling all the data on the net (linkeddata) through rpc isn't really usefull. We need sql like access, as has been demonstrated by yql.
Also, it doesn't have to expose the data-structure. Databases have long solved this problem using views. If you use a view, you can hide the implementation details. Same with REST.

POST can be mapped to any non-idempotent operation... by Dan Haywood

can't it? Not just to partial updates or creation of child resources.

And so that means it can map to arbitrary operations on (the resources that represent) domain objects.

Which, as others have indicated, means that REST != CRUD.

Dan

Re: POST can be mapped to any non-idempotent operation... by Andy Dent

can't it? Not just to partial updates or creation of child resources.

And so that means it can map to arbitrary operations on (the resources that represent) domain objects.
Only if you assume your destination system exposes such arbitrary operations. Without being rude, why do you assume a system does so - are you equating domain object interfaces in REST with unconstrained publication of all objects and operations?

Re: POST can be mapped to any non-idempotent operation... by Dan Haywood

Without being rude, why do you assume your destination system exposes such operations - are you equating domain object interfaces in REST with unconstrained publication of all objects and operations?


Well, in the systems I deal with (Naked Objects) this is precisely the point, to expose the public interface of the domain objects (by which I mean the domain objects' properties, collections and public actions) in a uniform manner so that they can be manipulated in a generic UI.

My interest is that I've developed a RESTful web service on front of NO, and we're now looking to develop generic OOUIs in RIA technologies (eg Silverlight) that will exploit it. It's early days for these OOUIs, but at any rate that's where I'm coming from on this.

Dan
consultant, trainer, author - developing enterprise applications
blog: danhaywood.com
books: "Domain Driven Design using Naked Objects", pragprog.com/titles/dhnako

Re: I respectfully disagree with the title of this blog post. by Bediako George

Hullo Christopher,

You are right that I left out HATEOAS. It is indeed an important part of REST.

I do understand your position with regards to CRUD being orthoganol to REST iff you are viewing CRUD as simply a direct consequence of relational database legacy.

I do not view CRUD in this way however. In my own opinion, the four CRUD operations represent a minimal set of operations you need to fully manipulate any resource, whether or not that resource is stored in a relational database, a content management system, a hashmap, or in your backyard shed. So I am not in agreement that these operations are bound by any such relational database legacy.

If you view CRUD in the manner that I view it, it makes sense to recognize it as a design approach that falls nicely under the category of constrained actions. Furthermore, I would submit that an adherence to the CRUD operations as a constrained set of actions in no way shape or form conflicts with an appreciation of HATEOAS.

This is the crux of my disagreement with the title of this blog post.

Regards,

Bediako

Allowed html: a,b,br,blockquote,i,li,pre,u,ul,p

Email me replies to any of my messages in this thread

Allowed html: a,b,br,blockquote,i,li,pre,u,ul,p

Email me replies to any of my messages in this thread

17 Discuss

Educational Content

General Feedback
Bugs
Advertising
Editorial
InfoQ.com and all content copyright © 2006-2014 C4Media Inc. InfoQ.com hosted at Contegix, the best ISP we've ever worked with.
Privacy policy
BT