15

I have just finished reading an article on MSDN by John Evdemon. He bashes the CRUD interfaces and calls it an anti-pattern.

While I agree that having ANYTHING stateful is difficult and Current and MoveNext are bad ideas I don't agree that CRUD as in Create Read Update and Delete are bad. If I have a car service and I want to let clients be able to do the basics, as in Create a car, get a cars details, update a cars details or delete a car then how are they meant to be able to do those things without CRUD operations.

Or what am I missing here?

Stephan
  • 4,263
  • 2
  • 24
  • 33
uriDium
  • 13,110
  • 20
  • 78
  • 138
  • 1
    I guess I'll have to read the article to get the answer: since when is cursor manipulation (moveNext) considered a CRUD operation? – mikemanne Oct 14 '10 at 13:09

4 Answers4

17

The CRUD interfaces should be avoided in distributed system / SOA scenario because they are very chatty. But should doesn't mean have to. When you have some client actions which require more than one call to your service then you know that you should give up CRUD approach and create new service operation which will agregate those calls into single call. When designing distributed system you should always reduce number of calls to minimum because network call is very time consuming.

Edit:

You can think about CRUD interface as about data access exposed in a service. Sometimes you really want this. But in SOA and distributed system architecture you are usually exposing business functionality which already wraps data access and offers much more complex operations (which agregate many data access operations).

Example:

CRUD x Business logic interface. Suppose that you are working with Invoices. Each invoice consists of an InvoiceHeader and one or more InvoiceLine. If you use a CRUD interface for invoice you will first call CreateInvoiceHeader operation to create InvoiceHeader and then several AddInvoiceLine operations to add all InvoiceLines - that is low level CRUD approach. But if you implement business logic on the service side you will call single CreateInvoice and pass a complex object graph (header with all lines) to the service to create and add what is needed. The Create method can also do other business operations like starting some workflow etc. That is common SOA and distributed system approach.

Ben
  • 54,723
  • 49
  • 178
  • 224
Ladislav Mrnka
  • 360,892
  • 59
  • 660
  • 670
  • That confuses me a bit. How do we let clients create new entities or update their details if we don't expose CRUD operations. For example Just a simple Create method that accepts a car. If there is a problem then we send back the fault. If you get nothing then it was successful. In my mind it can't get less chatty. Like I said I might be missing something big here. – uriDium Oct 14 '10 at 09:28
  • @uriDium: I added some example. – Ladislav Mrnka Oct 14 '10 at 09:35
  • Oh right. Thanks for the example. So CRUD in almost a "true form" where everything gets decomposed to basic Create Read Update or Delete is a bad idea because it forces chatty services. If you can wrap them all up in a single service method like for instance PlaceOrder(invoiceHeader, List) would be much better because it cuts down on the chat and makes more business sense. But there is obviously still a case where we might just need to create a single object. Am I getting the idea? – uriDium Oct 14 '10 at 09:42
  • @uriDium: Yes. But this was simple example. You can imagine much more complex or you can find another example where for example Update will need whole entity but client will post only simple value and service's business logic will be responsible for setting others. – Ladislav Mrnka Oct 14 '10 at 11:25
  • This is a decade old post sure, but still seemingly relevant. At the very basic level of any RDBMS you have tables that need CRUD operations performed, and building out an API manually would be tedious and chatty sure, but some of the modern frameworks like .NET Core implement automated data-first scaffolding by reverse engineering databases, so why not utilize it, and then on the DB end if you want to encapsulate lots of functionality, say adding a User account, you do so in a stored procedure mostly and then scaffold the call to the stored procedure? That makes it more reusable. – John Ernest Nov 30 '20 at 07:08
5

RESTfull web services which have been lately gaining popularity are proving wrong Mr. John Evdemon's post.

Boris Pavlović
  • 63,078
  • 28
  • 122
  • 148
  • 1
    I don't thinks so, he said "Developers should consult existing industry standards prior to developing their own schemas." Well HTTP with it's CRUD operation is the standard which you use with RESTfull web services. IMHO is the story here, it make no sense to define your own CRUD operations cause for CRUD operation there are enough solution already invented. – Stephan Sep 07 '11 at 08:54
5

I think he has on purpose designed the worst possible interface here and it is not really a CRUD interface.

<WebMethod()> _
Public Function MoveNext() As Boolean
End Function

<WebMethod()> _
Public Function Current() As Object
End Function

These two methods are obviously not stateless, but nor are they needed for a true CRUD interface. I think it just a very poorly written example and it is not really related to CRUD operations.

Update:

Found a similar question with a very good answer :)

Community
  • 1
  • 1
willcodejavaforfood
  • 43,223
  • 17
  • 81
  • 111
0

The accepted answer is incorrect. And despite the fact that John uses CRUD as a anti-pattern example using CRUD for are not bad for SOA. Here's the problem with SOA as John describes: it encourages increased complexity at the Service Level, which ultimately leads to less support for multiple use cases. One of the main reasons we build APIs is to provide access to multiple applications, this is where the primary ROI is in building APIs.

For example let say we have a blog API. Let say we give users the ability to write posts, add images and put comments in all on one screen of our external application. In John's vision of SOA he would probably recommend that we build our API to use one call to do all of these things so it would be less chatty and blah blah blah... so:

{
  "post_title": "New Post",
  "post_content": "Some Stuff....",
  "comments": [{
    "comment": "This is right on!",
    "userId": 101
  }, {
    "comment": "I agree.",
    "userId": 105
  }],
  "images": [{
    "imgURL": "http://some.img.com/1"
  }, {
    "imgURL": "http://some.img.com/2"
  }]
}

Now there are obviously three different data objects that need to be separately stored here: the post, the comments and the images. From the data store's perspective the post goes to the POSTS table the comments to the COMMENTS table and the images to the the IMAGES table. So if we build our service following the tenants of SOA as John describes them we make our one call with our object and it goes the the services which attempts to create the post which, for example purposes, works just fine then it attempts to create the comments which work fine but when we get to the images the service realizes that one of the image URLs is faulty are fails. So our service returns a failure? Even though 3 other parts are now successfully stored in our data store? Do we go back and undo all the parts that execute successfully? What if the data store has already committed the changes, and we can't roll it back?

Couple this with the fact that if we'd made it "more chatty" and submitted them individually we could now re-use those services in other applications without needing to re-write any part of the service.

The bad part of the consolidated services is that you are being sold on the idea that the service should never fail... which is ridiculous. There will always be an edge case where something will fail and by consolidating everything into to one service you have increased your complexity and actually increased your capacity to fail.

I would compare this version of SOA to the shortcomings we've already realized in building God Objects in Object Oriented Programming. https://en.wikipedia.org/wiki/God_object

We know better than this so why are we rehashing it? Consolidated or God Services are a bad idea just like God Objects. I say build your services to do one thing and do it well for as many use cases as you can and your service will be good.

Cleanshooter
  • 2,314
  • 4
  • 19
  • 29