Showing posts with label Viewpoint Flip. Show all posts
Showing posts with label Viewpoint Flip. Show all posts

Thursday, February 28, 2008

So What Gives SOAP its RPC Flavour?

(This is a summing-up of several threads from the past.)

When do we say that SOAP usage is RPC-style?

1. When we pretend to pass domain objects by reference but pass them by value?
2. When we use the "rpc/encoded" style instead of "document/literal"?
3. When we use WSDL (which forces request/response semantics) instead of SSDL?
4. When we expose domain methods as service operations without a viewpoint flip?

Not surprisingly, although all these criteria have merit, I'm now leaning towards the last view, because that represents my latest thinking. I believe that what makes SOA service-oriented is the flip in viewpoint from the inward-facing domain model to the way an external consumer would view the domain.

Example:

How we humans view our world (our "domain"):
Our behaviours - eat(), sleep(), makeMillionDollars(), payOffMortgage(), etc.

How aliens may view our world:
"Services" they can use - explore(), trade(), conquer(), etc.

I now think that if we achieve a semantic flipping of viewpoint from the methods within domain objects to the verbs that a "service interface" must expose, then we have decisively broken the RPC link.

1. There is no way we can pretend to be passing objects by reference. There is a very tenuous link between a method inside a domain object and a service verb, so the illusion of calling a local method on an object simply cannot exist.

2. The "rpc/encoded" style really doesn't hurt after the viewpoint flip is achieved. Does it really matter if we say

<param1/>
<param2/>

at the top level instead of having a single document root like this:

<method-name>
<param1/>
<param2/>
</method-name>

I don't think so. I think that's a technicality.

3. And even if WSDL forces request/response semantics on SOAP, a suitably viewpoint-flipped service is still not a remote procedure call because the service consumer still sees things their way.

On the other hand, if you take a domain method and (without a Viewpoint Flip) turn it into a SOAP operation in the doc/lit style, and also describe it in SSDL, I would say it's still RPC, because we're merely making domain methods remotely invocable.

So if that's all there is to it, let's call RPC "domain-oriented" in contrast to "service-oriented".

Friday, February 22, 2008

The Deciding Characteristic of SOA - The Viewpoint Flip

I used to tell the curious that SOA's distinguishing characteristic was loose coupling. That definition probably says it all who those who already "get" it, but probably fails to communicate anything meaningful to those who don't already know what it is.

These days, I try and emphasise one particular kind of loose coupling that I think epitomises what SOA is, and I call it The Viewpoint Flip. The Viewpoint Flip is a more tangible concept than "loose coupling", and therefore more practical advice to give to aspiring SOA architects. The Viewpoint Flip is more important than breaking the synchronous request-response paradigm and replacing it with asynchronous messaging - that's transport sugar. The more important decoupling happens in the application domain, and I'll talk about it again in this post, although I've covered it in the past. A recent discussion with a colleague has convinced me that this aspect of SOA is often underappreciated even by SOA practitioners. That's why I'm talking about it once again.

The flip in viewpoint that I'm talking about is from the application domain's own navel-gazing view of itself to the view of an external party who wishes to interact with the domain for their own purposes. It's not for nothing that SOA is called "service-oriented". You can't be service-oriented, even in the English sense of the term, if you're focused on your own view of the world. You need to think about what your customers want. Ironically, object-oriented systems (supposedly the pinnacle of modelling paradigms) may require the most wrenching viewpoint change, because their model is, by design, internally-focused. Older, procedural languages are often more naturally oriented to the viewpoint of an external party.

Two examples, one of which I've touched on before:

Take a drum (the musical instrument, not the vessel that stores water). Model its (State and) Behaviour using the OO paradigm. What methods can you think of that would model the drum's behaviour? If you said "beat()", you're still thinking procedurally. Beating is something you do to the drum, not something that the drum does. What the drum does in response to the beating is make a sound. Therefore "makeSound()" is an appropriate method for the Drum class. That's how you would model the domain. (If you had a Drummer class, then "beat()" could be a legitimate method of that class.)

But "makeSound()" is not a service-oriented verb! It's not what a prospective external user of the drum would do. It's too internally-focused. Funnily enough, "beat()" is a good service-oriented verb. Procedural thinking is alive and well in the SOA world, it would seem.

Another example is the common one of funds transfer between bank accounts. For some reason, this simple example seems to tie everyone up in knots. I've seen examples like this:
fromAccount.transferTo( toAccount, amount )
or alternatively,

toAccount.transferFrom( fromAccount, amount )
Neither of them is aesthetically satisfying. Neither of them models the inherent symmetry of the "transfer funds" operation.

What we want is an unashamedly procedural syntax

transfer( fromAccount, toAccount, amount )
But we're too tied up in OO thinking to be able to do this elegantly. But that, if I may point out, is precisely what we need to be able to say in SOA-speak.

Insight 1: SOA thinking requires a fallback to procedural logic. This is one of the fundamental drivers for the Viewpoint Flip.

[The Domain Model for the banking Account class would probably have methods like "acceptDebit()" and "acceptCredit()". The "transfer" verb would be modelled from the start as a Service, if one goes by the principles of Domain-Driven Design, because "transfer()" (whether to or from) is not part of the behaviour of the Account class. It's this non-Object-Oriented Service that would acquire the two account entities from a repository based on the identifiers passed to it, and then (transactionally) invoke the "acceptDebit()" method of one and the "acceptCredit()" method of the other.]

By the way, REST is beautifully elegant, partly because it achieves the Viewpoint Flip without anyone even noticing. GET, PUT, POST, DELETE - these are all things that you do. They're not verbs that model the behaviour of resources. They're verbs that model what service consumers do to resources. When you adopt the REST model, you are unconsciously forced into service-oriented thinking and away from object-oriented thinking. With SOAP/WS-*, there's a degree of conceptual sophistication that's demanded of the designer, without which the whole thing degenerates into a bunch of remote procedure calls in XML syntax, needlessly complex and brittle beyond belief.

If I may fire my pet arrow at SOAP in the eternal REST-vs-SOAP debate, the approach of many Web Services tool vendors is to generate SOAP interfaces and WSDL files by annotating methods on objects. This is so naive I don't know whether to laugh or cry. There is no annotation in the world that can cause the "makeSound()" method on a Drum class to transform itself into the "beat()" service that should be exposed to external systems. The Viewpoint Flip is a sophisticated conceptual exercise that only a human designer can engage in. If you rely on tooling to expose services from your domain objects, and you end up with a SOAP operation called "makeSound()", that's not SOA, that's a horrible Distributed Objects train wreck. Distributed Objects don't work.

In contrast, so many good things come together thanks to the singular concept of the Viewpoint Flip.

RPC goes out of the window, because we're not doing remote method calls. We're fundamentally transforming the nature of the verb. So it can't be about taking a local method on a class and making it remotely invocable. People have railed against SOAP-RPC for years (and I have as well), but the most damning argument against SOAP-RPC, I now realise, is that it doesn't implement the essential Viewpoint Flip that's required to turn a Domain Model into a Service Model.

Contract-First Design is another approach that emerges naturally out of accepting the need for the Viewpoint Flip. If you can't automatically generate a service interface from methods on objects, then it follows that it must be independently designed. In other words, the Service Interface and the Domain Model are independent, first-class entities. Neither can be generated from the other. They must be mapped to each other.

Did you notice that that's loose coupling? Change either the Domain Model or the Service Interface, and the other doesn't necessarily have to change. You may just have to change the mapping logic between them and hence preserve the other.

Nowadays, when someone asks me what SOA is all about, I don't glibly say "loose coupling." I say very slowly, "It's about being s-e-r-v-i-c-e o-r-i-e-n-t-e-d, being oriented to the viewpoint of the service consumer. SOA thinking means looking at a domain from the outside in, from the perspective of a consumer and what they wish to achieve, rather than how the domain sees itself, i.e., as a set of inter-related objects." [As Kirstan observes, it's also the most natural way in which a business analyst looks at the domain, i.e., as a set of service "steps" that can be composed into a business process.]

A bit of philosophy: I read somewhere that when a student embarks on the study of Zen, the mountains are nothing more than mountains. Partway through the training, the mountains are no longer mountains. But finally, when the student has mastered Zen, the mountains are once again mountains, but they're somehow not the same as what they were.

So let it be with models of the world. From procedural thinking to object-orientation and back again to procedural thinking. But this time around, procedural thinking isn't quite the same thing. It's service-oriented.