Everybody and their mother agrees that doing web services RPC-style is a Bad Thing™, but not many people would extend that to request/response, which is a useful and common pattern in any sort of remote communication scenario. It’s not as easy as one might imagine, though, to find out how the SOAP, WSDL and WS-A specs and the rest of WS-* stack can be used to support this pattern when combined with asynchronous messaging.
One approach is to view request/response as a logical pattern, independent from the transport or transfer protocol being used. The WSDL 1.1 note at W3C — a note because WSDL 1.1 is not a W3C recommendation — has this paragraph, which supports this:
Note that a request-response operation is an abstract notion; a particular binding must be consulted to determine how the messages are actually sent: within a single communication (such as a HTTP request/response), or as two independent communications (such as two HTTP requests).
I haven’t been able to find an example of a binding that uses this; interestingly, though, the recently published IBM RAMP profile clarifies and extends the WS-I guidelines as follows, clearly supporting the WSDL 1.1 view:
In the context of the WS-I Basic Profile, the only reason the response message to an HTTP request would be empty is when the request message is a one-way message. However, the WS-Addressing specification introduces a
wsa:ReplyTo
SOAP header block that changes the nature of a request/response WSDL operation as it relates to the HTTP binding. If a request message includes awsa:ReplyTo
header that does not use the WS-Addressing Anonymous URI, then the response message is expected to be sent to the wsa:ReplyTo endpoint reference (EPR) rather than in the HTTP response message. Since the response message will not be sent in the HTTP response message, the HTTP response code on the original connection would be “202 Accepted”. While this doesn’t violate any WS-I Basic Profile requirements it is a change in behavior.
When viewed this way, a request/response interaction is a logical pattern, while its mapping to either a single request/response transport interaction or two one-way message transfers is a non-functional aspect. If it is, though, I still haven’t been able to find a formalized way to express this (i.e. indicate to the runtime that it is supposed to treat the request/response interaction this way).
There’s also a second approach: View a logical request/response interaction as something that is conceptually one level above what is described by WSDL. This seems to be supported by WSDL 2.0, not yet, but soon supposed to become a W3C standard (recommendation):
This binding extension specification provides a binding to HTTP of Interface Operation components whose {message exchange pattern} property has the value “http://www.w3.org/2005/08/wsdl/in-only”, “http://www.w3.org/2005/08/wsdl/robust-in-only” or “http://www.w3.org/2005/08/wsdl/in-out”. This HTTP binding extension MAY be used with other message exchange patterns such as outbound message exchange patterns, provided that additional semantics are defined, such as with an extension or with a Feature.
Each of the supported message exchange patterns involves one to two messages or faults being exchanged. The first is transmitted using an HTTP request, and the second is transmitted using the corresponding HTTP response. In cases where only one message is being sent, the message body of the HTTP response MUST be empty.
Based on this, the only correct way to map a WSDL 2.0 request/response to HTTP (as one example) is to use the synchronous transport/transfer mechanism. To support a logical request/response interaction, one can use two WSDL one-ways (where the rule of the empty response is obviously violated by the RAMP profile (which is not a problem since it relies on WSDL 1.1)). In this case, though, some other mechanism is needed to indicate to the runtime infrastructure that two one-way messages should be correlated.
The motivation for this discussion is that the technology stack we’re currently using in one of my projects — a JBI container — quite directly maps WSDL 2.0 MEPs to runtime API constructs. If something is a WSDL 1.1 request-response (WSDL 2.0 in-out), the corresponding MessageExchange
created at runtime will be an InOut
object. This object will be used to send the request. When the JBI container receives an incoming response — even asynchronously, e.g. when using JMS or WS-A-based async HTTP messaging — it expects the InOut exchange which was used to send the request to be still alive. If it isn’t, it’ll view this as an error. But when something such as RAMP is used, the response might arrive not only minutes, but even days after the request has been sent.
We’re still trying to come up with a solution that seems natural enough for the poor person tasked with designing the WSDL, does not require us to implement lots of message-correlating infrastructure on top of JBI, and doesn’t seem like we’re abusing the technology … maybe what we need is a new WSDL 2.0 MEP (robust-in-robust-out
?)
You should use SSDL. These ridiculous WSDL 2.0 artefacts don’t exist when you consider the problem in terms of abitrary message exchange rather than some pre-canned silliness.
Jim