InfoQ

InfoQ

News

My Bookmarks

Login or Register to enable bookmarks for unlimited time.

The content has been bookmarked!

There was an error bookmarking this content! Please retry.

Is CRUD Bad for REST?

Posted by Boris Lublinsky on Jul 30, 2009

Sections
Architecture & Design,
Enterprise Architecture
Topics
Architecture ,
REST ,
Design ,
SOA
Tags
Service Design

 

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.

  • This article is part of a featured topic series on SOA

17 comments

Watch Thread Reply

First thing first. by Francois Ward Posted
Re: First thing first. by Boris Lublinsky Posted
I respectfully disagree with the title of this blog post. by Bediako George Posted
Re: I respectfully disagree with the title of this blog post. by Boris Lublinsky Posted
Re: I respectfully disagree with the title of this blog post. by Christopher Atkins Posted
Re: I respectfully disagree with the title of this blog post. by Boris Lublinsky Posted
Re: I respectfully disagree with the title of this blog post. by Christopher Atkins Posted
Re: I respectfully disagree with the title of this blog post. by William Martinez Posted
Re: I respectfully disagree with the title of this blog post. by Bediako George Posted
Versioning in REST? by Jean-Jacques Dubray Posted
PUT does not imply complete replacement by Andy Dent Posted
CRUD does not imply direct data access by Andy Dent Posted
CRUD not only good, but the only consistent way to build REST over HTTP by Dhananjay Nene Posted
Crud is actually pretty helpful by andrej koelewijn Posted
POST can be mapped to any non-idempotent operation... by Dan Haywood Posted
Re: POST can be mapped to any non-idempotent operation... by Andy Dent Posted
Re: POST can be mapped to any non-idempotent operation... by Dan Haywood Posted
  1. Back to top

    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...

  2. Back to top

    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!"?

  3. Back to top

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

    by Boris Lublinsky

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

  4. Back to top

    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

  5. Back to top

    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.

  6. Back to top

    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.

  7. Back to top

    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

  8. Back to top

    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.

  9. Back to top

    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

  10. Back to top

    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.

  11. Back to top

    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.

  12. Back to top

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

    by Dhananjay Nene

  13. Back to top

    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.

  14. Back to top

    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

  15. Back to top

    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?

  16. Back to top

    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

  17. Back to top

    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

Educational Content

10 tips on how to prevent business value risk

One category of risk that project teams need to ensure they address is business value failure – delivering a product that fails to provide value for the business investor.

Interview: Software Systems Architecture: Working With Stakeholders Using Viewpoints and Perspectives

InfoQ spoke to the authors of Software Systems Architecture on a couple of new topics, the System Context viewpoint and Agile, which have been added to the second edition.

Beauty Is in the Eye of the Beholder

Alex Papadimoulis discusses ugly code, where it comes from, how to avoid it, and how to get rid of it.

Architecting Visa for Massive Scale and Continuous Innovation

John Davies examines Visa’s architecture and shows how enterprises have architected complex integrations incorporating Hadoop, memcached, Ruby on Rails, and others to deliver innovative solutions.

Max Protect: Scalability and Caching at ESPN.com

Sean Comerford unveils ESPN.com’s architecture, what components are used and why, and the current changes the website goes through.

The Seven Deadly Sins of Enterprise Agile Adoption

Are there repeated patterns of failure on Enterprise Agile Enablement efforts? Sanjiv and Arlen discuss Seven Deadly Sins to avoid when adopting Agile in an enterprise.

Questions for an Enterprise Architect

Erik Dörnenburg answers: What is Enterprise and Evolutionary Architecture?, discussing 4 issues: Turning strategy into execution, Ensuring conformance, Where do the architects sit? Buying or building?

Wrap Your SQL Head Around Riak MapReduce

Sean Cribbs explains what Map-Reduce and Riak are, why and how to use Map-Reduce with Riak, and how to convert SQL queries into their Map-Reduce equivalents.