2

CRUD Operations in SOA:

Context to this question can be found here: Why are CRUD operations so bad in a SOA design?

I am working on an interface - Ex: Order, in which I have CreateOrder, UpdateOrder and GetOrder methods. The Order also has OrderLines. As I do not want CreateOrderLine, GetOrderLine as separate methods, I do those tasks through the CreateOrder and GetOrder methods. For a delete and an Update, the Update method should be called. But I am trying to work out a pattern for deleting a specific OrderLine. How do I work out the difference between an Update and a Delete? I have the following thoughts on how to achieve DeleteOrderLine:

Method 1:

1a: If you want one Order Line deleted: - Populate all the OrderLines in the request except the one the one(s) that you want deleted.

1b: If you want one order line updated: - Populate all the OrderLines in the request, with new values for the ones that you want updated.

2 Call UpdateOrder 3 The implementation deletes all OrderLineItems before starting any processing and always adds the Lines as if they were new.

Method 2: - Add some sort of 'command' to each order line ('Add','Delete','Update') which the implementation can use to perform an appropriate action. - For updates, mark the lines that need to be updated with the 'Update' command. Only these get updated. - For deletes, mark the lines that need to be deleted with the 'Delete' command. Only these get deleted.

Does anyone have any other ideas or mechanisms to make this work?

Thanks.

Community
  • 1
  • 1
Oxford
  • 139
  • 1
  • 2
  • 5

2 Answers2

1

Obviously, "easy CRUD" screams for a REST implementation. (No trolling or flamewar teasing intended, I am a SOAP implementer myself)

But assuming that you are still aiming for a SOAP implementation (because you nee XML schema validation, or your team is used to the technique, etc.), then I would push for a strict following of the Canonical Schema Pattern (Erl) and I would use your "Method 1".

Here is how & why:

How :

By that, I don't mean to start a new Data Architect Babel tower and figure out the schema for the "Order Canonical™" via a process of 10 weeks (a method sadly used often). I would rather push for quick review of the current schema used for the GetOrder response, and use THAT "object" in all operation, as is.

ie : the schema you use in the response of "get" would the same as the one in the requests of Create and Update operations. In fact Create and Update can often be merged to create an Upsert (often called Save in SOA operation). With this method The only difference is often lack of a primary key on creation.

This patterns forces "Method 1', and it is a good thing.

Why:

IMHO, Method 2 would rarely be quicker than method 1, even if it is more "optimized" (we only touch the OrderLines that needs to be edited, no other). Case in point : To delete/update a small number of lines with method 2, you have 2 choices : Do a lot of separate delete , or COMPOSE a single delete with a lot of precise WHERE clauses. With method 1 (and the canonical schema pattern), you delete ALL the OrderLines for the order ALL the time, and re-insert them. The algorithm is EASY and very maintainable.

If you respect this pattern, and use database transaction, DB corruption is not an issue for your "Method 1". Client generated are simpler (they have a lot of the same objects reused), and mediation of operation for an eventual composed service becomes really simple.

Disclaimer:

My logic is not completely sound if you have a MASSIVE number of OrderLine delete and updates do execute (I assume you don't, these a generally manual and seldom adjustments). If you DO have THAT many, then I would consider still having the same operation a stated above AND adding a specialized SaveOrderLine operation (but not a GetOrderLine or CreateOrderLine).

GhislainCote
  • 1,502
  • 11
  • 18
0

Method 2: - Add some sort of 'command' to each order line ('Add','Delete','Update') which the implementation can use to perform an appropriate action

Method 2 requires creation of some complex update operation graph stated in terms on objects:

var OrderUpdateDTO = new OrderUpdateDTO(
    OrderID = 23,
    CommentChange = "An example of Order property change",
    OrderLineUpdates = [
        new OrderLineCreateDTO(
            ProductID = 1025,
            Quantity = 3
        ),
        new OrderLineUpdateDTO(
            OrderLineID = 94,
            QuantityChange = 2
        ),
        new OrderLineDeleteDTO(
            OrderLineID = 95
        ),
        new OrderLineDeleteDTO(
            OrderLineID = 96
        )
    ]
)

The reason for such complex graph is SOA isn't supporting method composition (see here) and performance consideration (you can't many small CRUD service methods one by one, you must make a single call).

Once update graph is created, Service update method is called:

Service.Update(OrderUpdateDTO)

Service parses this update graph and invokes Business Logic Layer methods to apply these changes.

Does anyone have any other ideas or mechanisms to make this work?

Method 2 is seriously more complex than Method 1, because it requires:

  1. Work for a service developer to design update graphs and to implement logic for parsing update graphs
  2. Work for a service client to build update graph every time he changes something
Community
  • 1
  • 1
Lightman
  • 1,078
  • 11
  • 22