Coda Hale made a blog post that started some controversy and interesting debate some time back that I had missed. I started a comment which became lengthy enough to post here instead:
I think the root difference of this debate is that you have a very narrow interpretation of CRUD, coda, and by proxy, REST.
Most people would agree rdbms’s can be described as CRUD systems, yet their behavior is quite rich. Even just the R encompasses projection, generalized selection by arbitrary propositions, products (joins), etc. The key insight of Cobb’s relational database is that the basis of operators provided by relational algebra are sufficient for a huge domain of applications. Meanwhile the uniform interface allows a wide variety of client applications.
Likewise, in the REST thesis the concept of resource is quite rich, including resources that have behavior (ie the code on demand constraint). The CRUD part only applies to the uniform interface which is used between client and server to exchange representations. The domain of ‘RESTful’ applications is similarly large, as is the flexibility in clients.
On to specific responses:
How do you crop an image with CRUD?
Couple options:
Download an editor resource that can generate a preview and post/put the selected parameters.
Update an image model object via a request and return a server side generated image.
The interesting thing about case 1 is that the uniform interface constraint of REST implies that you could implement option 2, then implement option 1 to have client side preview calculation, but PUT/POST to the same URI as option 1 to store the finally selected crop parameters. I’m sure you can start thinking about how that might enable simple html, js and flash based editors to talk to the same server endpoint, and how this general principle is useful for eliminating code duplication.
ActiveResouce is likely to take this a step further and allow us to use the same sort uniform interface within our server side code, factoring out a single monolithic application into a cluster of cooperating services.
How do you browse a hierarchical set of categories?
Resources are typically structured in collections. Nothing says collections can’t be nested. Or more formally, our URI can represent a directed walk starting from any acceptable root of the data graph.
How do you retrieve all non-published articles? All articles which have the approval of the desk editor, but not the section editor, which havenât been flagged for review, with all their associated images, all the while checking that these actions are permissable according to the appropriate ACL with CRUD?
This is why we have query strings on collection resources (or matrix urls). Your very narrow view of CRUD seems to miss the concept of index, or that it might be predicated in some manner. Again this is similar to stating that databases aren’t CRUD because you can retrieve relations that match arbitrary criteria. Obviously databases can handle the above. Are we to decide databases aren’t CRUD?
At some point youâll be looking at your controllerâs actions, each of which is 80 lines long and contains nested case statements inside conditionals, each with an average of 10 different return paths, and youâll wonder where the hell all that simplicity went.
This was DHH’s key point. When this happens, the message is not “CRUD failed me”, but “My models need to be re-factored”.
There certainly are exceptions, but I think this perspective is quite useful in practice.