Saturday, March 22, 2008

RPC is Bad

In my last post I illustrated how we can achieve RPC style service interactions in an interoperable way using the wrapped document/literal style. However just because we can do something doesn't mean we should.

When using the document/literal style of messaging, RPC really becomes a matter of intent rather than message syntax. As was illustrated in my last post, we had both a message oriented syntax and RPC syntax with the same message on the wire.

With RPC, our intent is to invoke a method on the service producer with a given set of parameters. This tends to encourage exposing internal object methods as service operations, leading to poor encapsulation. The number, name and type of method parameters are an implementation detail of the service which should be encapsulated behind the service boundary. With RPC, they end up in the service contract.

This then leads to poor service contract design. Deriving the service contract from method signatures is dangerous. The service contract and the messages it defines are first class citizens in SOA and need to be explicitly designed and highly visible.

Semantically, we need to be thinking about sending or publishing messages that have business-level relevance. When we are thinking in terms of RPC, we are focussed more on service implementation details than the message.

Also, RPC style interactions tend to lead to fine grained communications. That is, we result in many small messages rather than fewer larger messages. This is because developers naturally wish to limit the number of parameters in a method signature. This then has negative performance connotations.

The RPC approach is also not very version tolerant. If we add or remove a parameter from our method signature, old versions of the message will not be able to be processed by newer versions of the service. This means we have fewer options for updating service producers without also updating all their consumers at the same time. This means more coupling between our services.

Furthermore, RPC tends to lead developers down the path of returning values from the methods being invoked on the service. This leads to synchronous request/reply, which is a bad idea for reasons explained here.

And finally, RPC style interactions obscure the fact that a message is being sent over a network boundary by providing an interface at the service consumer that looks local. One of the tenets of SOA is that boundaries are explicit. Due to the fallacies of distributed computing, we cannot hide the network boundary from service developers. Distributing objects in a way that makes then look local (as was done by DCOM and .NET Remoting) has led to a number of failed implementations.

So in conclusion, avoid RPC style interactions between services in favour of a message centric approach.