Lightman
Lightman

Reputation: 1265

Does SOA support method composition?

There is a good example taken here:

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.

Why a perfectly legal method composition

var Invoice = 
    Service.CreateInvoice(
        Service.CreateInvoiceHeader(...),
        {
            Service.CreateInvoiceLine(...),
            Service.CreateInvoiceLine(...)
        }
    )
  1. is absolutely awful from performance point of view when used in SOA?
  2. can't be translated automatically into a single Service call?

Why must one instead create a complex object graph and send it to the service method

var InvoiceDTO = new InvoiceDTO(
    new InvoiceHeaderDTO(...),
    {
         new InvoiceLineDTO(...),
         new InvoiceLineDTO(...)
    }
)

var Invoice = Service.Create(InvoiceDTO)

and the Service must traverse the whole graph and call just the same Service methods to assemble the resulting Invoice?

Is there any way to use method composition to create complex results without using complex object graphs as data transport?

Upvotes: 0

Views: 43

Answers (1)

btilly
btilly

Reputation: 46408

The answer is that with a SOA architecture your performance bottleneck is that round trips are expensive. They add latency, work for your network and CPU overhead.

There are several basic mitigation strategies.

  1. Put things that talk to each other close together. In the same process is optimal. On the same machine helps a lot. Close by in the data center still helps. The downside of this approach is that how much you can put together is limited by machine size.

  2. Break work into more granular chunks to minimize how many round trips will happen. The downside of this approach is that the interactions left are likely to be more complicated (your "complex object graph" is an example).

  3. Use more efficient protocols. Really smart people laughed at XML as an RPC protocol in the last millennium. Smart people realized a decade ago that it was stupid. A lot of organizations still use it. Stop. Use JSON, Cap'n Proto, or something else. The only downside is the organizational challenge of getting people to agree on what to do instead.

  4. Make calls in parallel. That is don't send 50 requests one at a time. Send them together and process them when they come back. The downside is that this adds considerably to code complexity and only helps with latency - resource consumption is not helped.

You do not have to choose among these options. Companies with good SOA architectures (eg Google) do all 4.

That said, back to your question. There is a middle ground. Rather than making a call with a complex object what you can do is make a call to create an object, make various calls to build up the data structure, and then make a call to actually send it. The code looks exactly like what you wrote with the low level CRUD interface, except that there is a Service.Send() call at the end which actually sends off the request.

Upvotes: 2

Related Questions