In a Web service-based SOA design, XML schemas are usually defined for both providers and consumers for data exchange. To define such commonly agreed-upon schemas is the first step for interoperability, but not necessarily a guarantee of a successful data exchange. To ensure an overall interoperable data transaction using Web services, SOAP messages have to be taken into consideration as well.
An XML payload is typically wrapped in a SOAP message for data transportation. Without a correct design of a SOAP message, an XML payload may not be exchanged properly even if the payload follows a common XML schema for both providers and consumers. SOAP message structure is determined by SOAP binding definition in a WSDL document. The case study in this article describes how WSDL definitions can impact SOAP message and data exchange.
The following sequence diagram illustrates a case in which an integration layer is involved for data exchange in a Web service-based SOA. System A is a data system that publishes its data to integration layer which relays the data to downstream systems such as System B using Web services. The integration layer acts as an intermediary service for the data transaction. It provides functions such as service aggregation and orchestration. It controls the data flow between the data system A and B in this case.
Theoretically an integration layer is not necessarily needed in SOA-based integration, but the reality is that it is rarely successful without it. The case we have here fits in a SOA using an integration layer for data flow control and service orchestration, which provides the necessary de-coupling of systems to be integrated. This article focuses on how to design Web services properly to achieve interoperability for data exchange at the SOAP level.
Two Web services are involved in this data exchange case: publishSomeData and receiveSomeData service. The publishSomeData Web service is implemented by the integration layer for publishing data from System A. The System A is the consumer of the publishSomeData Web service. It invokes the "publish" service at the integration layer to send a publishSomeDataRequest message to broadcast its data in XML format wrapped in a SOAP envelop. Once the message is received by the integration layer, a response message, publishSomeDataResponse, is sent back to the System A.
After the integration layer receives the message payload, it checks with its orchestration service to see which systems are subscribed for the data. It then passes the message to the receiver System B by invoking the "receive" service, receiveSomeData, provided by the System B.
To simplify the case study, the following XML message payload is used as an example:
Listing 1. XML message payload
<SomeData> <ID>123456789</ID> <Value>33.99</Value> </SomeData>
This piece of XML payload can be presented in a SOAP message in two different styles: Remote Procedure Calls (RPC) and document. In RPC style, the XML payload is wrapped inside an operation element in a SOAP body. A document style message, on the other hand, has the XML payload directly placed in a SOAP body. Both the RPC and document message can be either a literal or encoded message. Since the Encoded style is not supported by WS-I, we will not cover it in this article. A literal message implies that a schema is utilized to provide a description and constraint for an XML payload in SOAP. Here both RPC-literal and document-literal styles are used in the case study.
SOAP binding, RPC style
In a RPC-literal style, a service consumer invokes a Web service as a remote procedure call. It sends a message with inputs as parameters. The literal XML payload is encapsulated in a SOAP message prior to an invocation over a transport protocol like HTTP.
A typical RPC SOAP message sent from the service consumer, System A, is listed as below:
Listing 2. RPC SOAP message sent from the service consumer, System A
<soap:Envelope > ... <soap:Body> <publishSomeData> <SomeData> <ID>123456789</ID> <Value>33.99</Value> </SomeData> </publishSomeData> </soap:Body> </soap:Envelope>
The <publishSomeData> is the operation name that System A invokes. The <SomeData> content is the input parameter for the operation.
As mentioned above, how a SOAP message is constructed is mainly determined in a WSDL document. To construct such a SOAP message, a SOAP binding in a WSDL document can be defined as:
Listing 3. Defining SOAP binding in a WSDL document
... <wsdl:binding name="PublishSomeData_Binding" type="tns:PublishSomeData"> <soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/> <wsdl:operation name="publishSomeData"> <soap:operation style="rpc" soapAction= "http://www.someCompany.com/soa/2005-03-06/publishSomeData"/> <wsdl:input> <soap:body use="literal" namespace= "http://www.someCompany.com/soa/2005-03-06/publishSomeData.wsdl"/> "http://www.someCompany.com/soa/2005-03-06/publishSomeData.wsdl"/> </wsdl:input> <wsdl:output> <soap:body use="literal" namespace= "http://www.someCompany.com/soa/2005-03-06/publishSomeData.wsdl"/> </wsdl:output> </wsdl:operation> </wsdl:binding>
Note that the soap:binding style is "rpc" and the wsdl:operation name is the element that is contained in the <soap:Body> in the SOAP message.
The data flow starts with an invocation from the System A with a call to the publishSomeData service at the integration layer. After the integration layer receives the XML message in a SOAP envelope, it responds to System A with an acknowledgement. The integration layer then passes the SOAP message to the receiver by invoking receiveSomeData service at receiver end, System B. Usually the integration layer does not open the SOAP envelope to process the XML payload. Again it only acts as an intermediary service to control the data flow and ensure the data being received correctly.
At the receiver end, System B expects an incoming SOAP message in RPC style according to its own WSDL definition. As a "receive" service, its WSDL operation is typically defined as below:
Listing 4. WSDL operation
<wsdl:operation name="receiveSomeData"> <soap:operation style="rpc" soapAction= "http://www.someCompany.com/soa/2005-03-06/receiveSomeData"/> <wsdl:input> <soap:body use="literal" namespace= "http://www.someCompany.com/soa/2005-03-06/receiveSomeData.wsdl"/> </wsdl:input> <wsdl:output> <soap:body use="literal" namespace= "http://www.someCompany.com/soa/2005-03-06/receiveSomeData.wsdl"/> </wsdl:output> </wsdl:operation>
Note that the operation in the "receive" service is named "receiveSomeData" and is not the same as the one defined in the integration layer for the "publish" service. An operation name is typically defined based on its role in a SOA such as "publish" for a publish service and "receive" for a receive service. At the receiver end, the role of the service is to "receive".
According to the wsdl:operation definition, the receiver Web service interface expects a RPC-style SOAP message wrapped with a receive operation listed as below:
Listing 5. RPC-style SOAP message wrapped with a receive operation
<soap:Envelope > ... <soap:Body> <receiveSomeData> <SomeData> <ID>123456789</ID> <Value>33.99</Value> </SomeData> </receiveSomeData> </soap:Body> </soap:Envelope>
Obviously, the SOAP message that the integration layer relays from the source system, System A, cannot be processed because it contains a different operation name, "publishSomeData". As a result, the data exchange is failed in this case.
There are a number of ways to solve the problem. One way is for the integration layer to process the SOAP message and to reconstruct a different SOAP message with a proper operation name. However, it can cause extra processing within the integration layer. A preferred way to resolve this problem is to use document-literal style SOAP message with an assumption that both "rpc" and "document" style are allowed for this particular integration.
SOAP binding, document style
In a document-literal style SOAP message, only an XML payload is placed in SOAP body without the operation name wrapped. A typical document style SOAP message looks like the one below:
Listing 6. Typical document style SOAP message
<soap:Envelope> ... <soap:Body> <SomeData> <ID>123456789</ID> <Value>33.99</Value> </SomeData> </soap:Body> </soap:Envelope>
Note that the operation name <publishSomeData> is not presented in the SOAP body anymore. The SOAP body only contains the XML payload. To construct the SOAP message listed above, here is the WSDL binding definition:
Listing 7. WSDL binding definition
... <wsdl:binding name="PublishSomeData_Binding" type="tns:PublishSomeData"> <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/> <wsdl:operation name="publishSomeData"> <soap:operation style="document" soapAction= "http://www.someCompany.com/soa/2005-03-06/publishSomeData"/> <wsdl:input name="SomeData"> <soap:body use="literal"/> </wsdl:input> <wsdl:output name="returnData"> <soap:body use="literal"/> </wsdl:output> </wsdl:operation> </wsdl:binding>
Now let's look at the data flow again from System A to B through the integration layer. The integration layer does not act differently at all. It receives the data from the System A and then simply passes it to the receiver, System B. The Web service at the receiver end has to be defined to accept a document style message for the data exchange in this case. By doing so, the interoperability issue with the RPC style can be avoided since there is no particular operation name presented in the SOAP message.
As for a document message, there are two additional styles:wrapped and unwrapped. The wrapped document-literal style is used to mimic a RPC style. In a document wrapped style, the wsdl:operation name has to be defined the same as the name of the root element of an XML document. The document message listed above is an unwrapped document style with different operation and schema element name. In the document-wrapped SOAP message below, the schema root element is renamed to <publishSomeData> to match the operation name defined in its WSDL document.
Listing 8. Document-wrapped SOAP message
<soap:Envelope > ... <soap:Body> <publishSomeData> <ID>123456789</ID> <Value>33.99</Value> </publishSomeData> </soap:Body> </soap:Envelope>
The XML payload is now presented with the root element as "publishSomeData" which is the same name as the wsdl:operation of the "publish" service.
The receiver end should have no problem to accept such document style SOAP message as long as the same schema defined in receiver's WSDL. However, it breaks the SOA role pattern that a "receive" operation should be defined at receiver end and "publish" at publish side. To use a "publish" element in a "receive" schema simply violates the semantics of a "receive" service. In this scenario the syntax may be correct for a document-wrapped style, but not necessarily a good practice for SOA implementation.
In summary, interoperability has to be achieved at the SOAP level as well as the XML payload level. Varieties of SOAP message styles can be utilized for a data exchange with different combinations in WSDLs. It is not necessarily true that one style is better than another, but any selection of a message style should meet business and integration needs. In the case presented in this article, the document-literal with unwrapped style is a fit.
- "Which style of WSDL should I use" (developerWorks, October 2003) describes different combinations for WSDL and SOAP messages.
- Web Service Interoperability Organization provides details on WS-I Basic Profile.
- Stay current with developerWorks technical events and Webcasts.
Get products and technologies
- Participate in developerWorks blogs and get involved in the developerWorks community.
Dig deeper into SOA and web services on developerWorks
Get samples, articles, product docs, and community resources to help build, deploy, and manage your cloud apps.
Keep up with the best and latest technical info to help you tackle your development challenges.
Software development in the cloud. Register today to create a project.
Evaluate IBM software and solutions, and transform challenges into opportunities.