It must be me... I can't explain it otherwise. I must have the wrong understanding.
First, it was the Grid community with OGSI and their non-standard-based, object-oriented approach to building Grid Services, then it was WS-RF with their resource-oriented view of the world and their state lifetime management, and now it's WS-Transfer which looks like REST but it's not exactly REST.
Conceptually, messages are no longer targeted to services but, rather, to resources. This is the case with REST and WS-RF too. I pointed this out in a previous post and in a message to the WS-RF mailing list. Jimwrote about the same issue too.
The problem is the particular use of WS-Addressing. I don't have a problem with the specification, which is great, but with the way it's used by WS-RF and WS-Transfer where it effectively becomes the equivalent of an object/resource pointer/identifier. I like the use of WS-Addressing in specifications like WS-Eventing (apart from the unsubscribe message). It makes it easy to build message-oriented applications, protocols, and patterns (e.g., "third-party delivery" and "multi-node flow" posts).
So what's the issue with the particular use of WS-Addressing? Let me take you through a simple example.
If you had already ordered two cars from a car dealer and you wanted to update the orders with new colours, what would you do? Would you have done business with a car dealer that required you to send each update in turn? What if you had 1,000 orders or 1 million? Would you be prepared to send each of those updated orders in turn?
What REST, WS-RF, and now WS-Transfer tell us is that each order can be treated as an addressable resource whose state is represented onto the network as a document. This means, at the architecture level, we don't reason in terms of services anymore but, rather, in terms of resources. My updated order for car 415,324 would be sent as...
<soap:Envelope>
<soap:Header>
<soap:Action>http://schemas.xmlsoap.org/ws/2004/09/transfer/Put </soap:Action>
<soap:To>uri:car-dealer </soap:To>
<car:order-number>415,325</car:order-number>
</soap:Header>
<soap:Body>
<car:order-update>
<car:colour>blue</car:colour>
</car:order-update>
</soap:Body>
</soap:Envelope>
So, where do we send the new state?
Well... to the order-resource; not the service that knows about the resource. At least that's what we do conceptually. That's how we reason about this at the application's architecture. Here we have a case where a specification changes our view of the architecture. It seems that services have disappeared (at the architecture level) and given their place to resources.
What's wrong with doing this instead?
<soap:Envelope>
<soap:Header>
<soap:Action>why:do:I:need:an:action?</soap:Action>
<soap:To>uri:car-dealer </soap:To>
</soap:Header>
<soap:Body>
<car:order-update>
<car:order>
<car:order-number>415,325</car:order-number>
<car:colour>blue</car:colour>
<car:order>
</car:order-update>
</soap:Body>
</soap:Envelope>
This says that the document order-update
should be delivered to the car dealer. What's more, we can now do the following which is not easy with the resource-oriented approach:
<soap:Envelope>
<soap:Header>
<soap:Action>why:do:I:need:an:action?</soap:Action>
<soap:To>uri:car-dealer </soap:To>
</soap:Header>
<soap:Body>
<car:order-update>
<car:order>
<car:order-number>415,325</car:order-number>
<car:colour>blue</car:colour>
<car:order>
<car:order>
<car:order-number>415,326</car:order-number>
<car:colour>pink</car:colour>
<car:order>
<car:order>
<car:order-number>415,327</car:order-number>
<car:colour>red</car:colour>
<car:order>
</car:order-update>
</soap:Body>
</soap:Envelope>
You see? Three updates in one go and the logical recipient is always the service, not the resource.
Yes, yes, yes... you can model solutions where the resource receiving the message is the representation of an order-processing system but that's forcing you to expose as a resource yet another aspect of your service's internals, a process. Autonomy? Service boundaries?
Don Box suggests that we are eventually going to like the concept. Well, I've been trying to understand REST for some time now and I think I got it (Mark Baker?) but I still prefer service-orientation and the transfer of documents through message exchanges (always SOAP). But then again, who am I to talk to Don! about service-orientation?
IMHO, the use of the term "operation" in WSDL has done a lot of harm. I now wish that Jim and I had fought harder to support our recommendation to the WSDL WG to rename "operation" to "interaction". There are many who think that a "portType" or an "interface" carry application semantics. If we ignore the bad choice of names, a WSDL document only describes message exchanges while the input
and output
elements describe the format of the messages that make those exchanges. There is no suggestion (at least there shouldn't be) about the existence of operations or any other abstractions and their dispatch-related mechanisms. Any application-specific semantics are defined in the specifications that govern the documents being transferred.
I believe that we don't need multiple verbs/operations; we don't even need a limited number of them; but if we are absolutely desperate for a verb, then we can assume that there is only one called "ProcessMessage" which represents a door to the service boundaries. Messages entering the door disappear beyond those boundaries. As both Jim and I have previously described (just google "ProcessMessage" or "ProcessThis") we only have this one logical operation which is eventually replaced by transport-specific mechanisms like TCP/IP send/receive, SMTP verbs, HTTP PUT/POST, etc. So why introduce additional verbs? What do they add? And, offering an alternative to Don's example, couldn't we send the following message instead of having to overload the semantics of PUT?
<soap:Envelope>
<soap:Header>
<soap:Action>why:do:I:need:an:action?</soap:Action>
<soap:To>uri:machine-management-service</soap:To>
</soap:Header>
<soap:Body>
<management:shutdown-request>
<management:log>logging-service-EPR</management:log>
</management:shutdown-request>
</soap:Body>
</soap:Envelope>
The semantics of receiving a management:shutdown-request
document are defined by the "WS-MachineManagement" specification. No operations. Just documents being transferred using SOAP.
(I never imagined I was going to disagree with Don... I must be wrong or I must be missing something. I do hope we'll see more descriptions/explanations/examples of the indented use of WS-Transfer.)
Finally, it seems to me that the idea of allowing representations of state to be referenced and becoming logical recipients of messages, albeit only through basic operations, goes against the principles that Pat Helland describes in his "Data on the Outside vs. Data on the Inside" paper to which I recently linked. Data inside the boundaries of the service are referred in the outside world by name. They are not addressed explicitly and certainly don't become recipients of messages; that's what services are for.
It seems to me that fewer and fewer people believe in the pure service-oriented approach. I start to feel lonely in this world (ok... there is also Jim but he doesn't count because he's a friend 🙂
10 responses to “WS-Transfer: I must be missing something (and I feel lonely)”