Dilip pointed me to recent posts from Savas and Jim about “message transfer”, or MEST. It's an interesting idea and I told him I'd post my thoughts (sorry for the delay Dilip :-).
As far as I can tell, the basic idea behind MEST is that web services developers should be thinking about message passing instead of RPC calls. I completely agree. But I disagree with the idea that that means there should be one WSDL interface with one operation “ProcessMessage”. There's no need to go there, because we're there already.
WSDL 1.1 has four generic message exchange patterns (MEPs), only two of which have meaning over HTTP: request/response and oneway. Request/response means “process this message and send me a response” and oneway means “process this message and don't send me a response”. When you write a WSDL portType definition, you're really creating a named list of named MEPs. Each named MEP (or operation) “instantiates” one of the generic MEPs by providing input and output elements (via the useless WSDL message construct). This information is useful, because it tells you the specific messages that a service will process and in the case of request/response MEPs, the message it will return.
The trouble starts when toolkits generate service and client code from a WSDL description. Most of them generate a class with a bunch of method calls. Each method call has multiple arguments that correspond to the sub-pieces of the message. This definitely pushes developers to think of Web services as just another RPC mechanism, which they aren't. It's important to note, however, that this is a toolkit, code-gen issue, not a WSDL design issue. Moving to a single generic ProcessMessage operation is a way to work around the misdirected path most toolkits take. There are other approaches that will achieve the same goal, however, and don't require convincing everyone that they should write their WSDL portTypes that way (which isn't going to happen).
One simple step is to map an entire input or output message to an argument. In this model, you still use classes with methods, but they take a single input argument representing the request message and optionally return a single argument representing the response message. You can do this with ASMX by defining wrapped messages (where there is an outer-most element the conveys the message's intent, e.g., “CheckPrice“) in your contract but programming with them as bare messages. The dispatcher will map each message to one arg instead of pulling them apart.
That model is okay, but still looks like method calls, albeit ones that see entire messages as first-class arguments. If that isn't enough you can use the lower level messaging API in WSE2 (which, in case I've never said, is IMHO the best WS toolkit shipping today!). The SoapClient/SoapService classes provide a cleaner implementation of the wrapped/bare trick in ASMX - operations map to methods that take a single input argument and return an optional argument. Arguments always represent entire messages. You can go even deeper, though. First, you can use SoapClient generically without a type-safe proxy by deriving a generic proxy type that calls SoapClient's invoke methods passing an action URI and a message. That's the client side of “ProcessMessage”, no matter what the WSDL says. You can also use SoapSender and SoapReceiver to build whatever programming model you want - async, event based, method calls, or any mix.
So, while I'm behind the MEST, I'm not behind the argument that there should be only one ProcessMessage operation in your WSDL portType. We don't need to go there because that abstraction already exists further down in the stack. The right way to get where MEST wants to go is to focus on popularizing alternative programming models, perhaps by building something really slick on WSE2 or Indigo (if it isn't there already).
Posted
Feb 10 2005, 08:19 AM
by
tim-ewald