- From: Jean-Jacques Moreau <moreau@crf.canon.fr>
- Date: Tue, 09 Apr 2002 09:52:31 +0200
- To: Web Service Description <www-ws-desc@w3.org>
- CC: Sanjiva Weerawarana <sanjiva@watson.ibm.com>, Arthur Ryman <ryman@ca.ibm.com>
ryman@ca.ibm.com wrote: > Jean-Jacques, > > Pls add this issues to the list:(See attached file: wsdl11-issues.zip)Thx. > See you in San Jose. > > Arthur Ryman, PhD > Senior Technical Staff Member > WebSphere Studio Advanced Development and Web Services Tools Architect > > phone: 905-413-3077, TL 969-3077 > assistant: 905-413-2323, TL 969-2323 > fax: 905-413-4920, TL 969-4920 > intranet: http://w3.torolab.ibm.com/~ryman/ > > ----------------------------------------------------------------- > Name: wsdl11-issues.zip > wsdl11-issues.zip Type: Zip Compressed Data (application/x-zip-compressed) > Encoding: base64 [WSDL 1.1 Issues.html converted to plain text.] WSDL 1.1 Issues Arthur Ryman 2002-04-07 Introduction This document describes some issues with WSDL 1.1 that were encountered during the development of Web services tools at IBM. The main issues encountered are: 1. The binding extensions depend on the structure of the portType. 2. The binding extension for SOAP is defined in terms of features that interact in a complex way. 3. The binding extension for SOAP cannot describe SOAP messages that mix encoding styles at the message part level. 4. The binding extension for HTTP GET or POST does not cover the case of attributes in a complex input type. These issues are described in more detail below. Binding Extensions Depend on the Structure of the portType The portType is supposed to represent the abstract interface of a service without reference to how the service is accessed. However, the current design couples the binding extensions with the structure of the portType making it necessary to define a separate portType for each binding extension. SOAP RPC Style, SOAP Document Style, and HTTP GET or PORT each require specific structure in the portType, yet all can be used to access the same logical service. It is useful to provide HTTP GET and POST endpoints for a service in addition to a SOAP/HTTP endpoint. Each endpoint should provide access to the same underlying service. It is therefore reasonable to expect that each endpoint should be bound to the same portType. The portType should be an abstract definition of the interface of the service. The bindings should describe how to access the service using a given protocol. However, the binding extensions for HTTP GET and POST are not defined in a way that allows them to use the same portType as SOAP/HTTP. To work around this problem, an additional, but semantically equivalent portType, must be defined. To illustrate this problem, consider a stock quote service that has a single operation, getQuote, that takes a string symbol as input and returns a float price as output. Consider the WSDL for this service as created using: * IBM WebSphere Studio: IBMStockQuoteService.wsdl * Microsoft Visual Studio .NET: MSStockQuoteService.wsdl WSDL 1.1 defines messages as collections of parts. It is therefore natural to define the input message as having a single part named symbol of type string, and the output message to have a single part named price or return of type float. With this definition of messages, the SOAP binding is naturally expressed using the RPC style. Listing 1 shows the SOAP binding definitions from IBMStockQuoteService.wsdl: Listing 1. IBMStockQuoteService.wsdl SOAP RPC Style Binding <message name="getQuoteInput"> <part name="symbol" type="xsd:string"/> </message> <message name="getQuoteSoapOutput"> <part name="return" type="xsd:float"/> </message> <portType name="theSoapPortType"> <operation name="getQuote"> <input message="tns:getQuoteInput"/> <output message="tns:getQuoteSoapOutput"/> </operation> </portType> <binding name="theSoapBinding" type="tns:theSoapPortType"> <soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/> <operation name="getQuote"> <soap:operation soapAction="http://tempuri.org/isd/StockQuoteService.isd"/> <input> <soap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="http://tempuri.org/isd/StockQuoteService.isd" parts="symbol" use="encoded"/> </input> <output> <soap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="http://tempuri.org/isd/StockQuoteService.isd" parts="return" use="encoded"/> </output> </operation> </binding> However, this portType cannot be used for HTTP GET or POST because the we want the output to be of MIME type text/xml. Simply returning a float is not allowed because a float is just an XML fragment, not a valid document. We therefore need to define a new output message and portType as shown in Listing 2. Listing 2. IBM StockQuote.wsdl HTTP GET and POST Bindings <types> <schema targetNamespace="http://schemas.ibm.com/beans/StockQuoteService.isd/XSD" xmlns="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://schemas.ibm.com/beans/StockQuoteService.isd/XSD"> <element name="getQuoteResponse"> <complexType> <sequence> <element name="return" type="float"/> </sequence> </complexType> </element> </schema> </types> <message name="getQuoteGetPostOutput"> <part element="xsd1:getQuoteResponse" name="response"/> </message> <portType name="theGetPostPortType"> <operation name="getQuote"> <wsdl:documentation xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">Gets a quote in US dollars for a stock symbol. </wsdl:documentation> <input message="tns:getQuoteInput"/> <output message="tns:getQuoteGetPostOutput"/> </operation> </portType> <binding name="theGetBinding" type="tns:theGetPostPortType"> <http:binding verb="GET"/> <operation name="getQuote"> <http:operation location="getQuote"/> <input> <http:urlEncoded/> </input> <output> <mime:mimeXml/> </output> </operation> </binding> <binding name="thePostBinding" type="tns:theGetPostPortType"> <http:binding verb="POST"/> <operation name="getQuote"> <http:operation location="getQuote"/> <input> <mime:content type="application/x-www-form-urlencoded"/> </input> <output> <mime:mimeXml/> </output> </operation> </binding> In Listing 2, getQuoteReponse has a root element that includes all the output message parts as children. This style of response accommodates any number of output message parts (zero, one, or more than one). Listing 3 shows a typical response using the getQuoteResponse element (see IBMgetQuoteResponse.xml). Listing 3. IBMStockQuoteService.wsdl HTTP GET or POST Response <?xml version="1.0"?> <xsd1:getQuoteResponse xmlns:xsd1="http://schemas.ibm.com/beans/StockQuoteService.isd/XSD" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <return xsi:type="xsd:float">100.0</return> </xsd1:getQuoteResponse> The need for a different portType cannot be eliminated by using SOAP Document style instead of RPC style. Although Document style defines a suitable output message, the input message is not suitable for URL encoding. Although in this example, there is just one input message part, in general there will be more than one part and each part should be bound as a name=value portion of the query string in URL encoding. Listing 4 shows the SOAP Document style bindings from MSStockService.wsdl. Listing 4. MSStockQuoteService.wsdl SOAP Document Style Bindings <types> <s:schema elementFormDefault="qualified" targetNamespace="http://microsoft.com/webservices/"> <s:element name="getQuote"> <s:complexType> <s:sequence> <s:element minOccurs="0" maxOccurs="1" name="symbol" type="s:string" /> </s:sequence> </s:complexType> </s:element> <s:element name="getQuoteResponse"> <s:complexType> <s:sequence> <s:element minOccurs="1" maxOccurs="1" name="getQuoteResult" type="s:float" /> </s:sequence> </s:complexType> </s:element> </s:schema> </types> <message name="getQuoteSoapIn"> <part name="parameters" element="s0:getQuote" /> </message> <message name="getQuoteSoapOut"> <part name="parameters" element="s0:getQuoteResponse" /> </message> <portType name="StockQuoteServiceSoap"> <operation name="getQuote"> <input message="s0:getQuoteSoapIn" /> <output message="s0:getQuoteSoapOut" /> </operation> </portType> <binding name="StockQuoteServiceSoap" type="s0:StockQuoteServiceSoap"> <soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document" /> <operation name="getQuote"> <soap:operation soapAction="http://microsoft.com/webservices/getQuote" style="document" /> <input> <soap:body use="literal" /> </input> <output> <soap:body use="literal" /> </output> </operation> </binding> Note that the messages for the SOAP Document style binding are different than those for the SOAP RPC style binding even though they both describe the same service. Listing 5 shows the HTTP GET and POST bindings. Listing 5. MSStockQuoteService.wsdl HTTP GET and POST Bindings <types> <s:schema elementFormDefault="qualified" targetNamespace="http://microsoft.com/webservices/"> <s:element name="float" type="s:float" /> </s:schema> </types> <message name="getQuoteHttpGetIn"> <part name="symbol" type="s:string" /> </message> <message name="getQuoteHttpGetOut"> <part name="Body" element="s0:float" /> </message> <message name="getQuoteHttpPostIn"> <part name="symbol" type="s:string" /> </message> <message name="getQuoteHttpPostOut"> <part name="Body" element="s0:float" /> </message> <portType name="StockQuoteServiceHttpGet"> <operation name="getQuote"> <input message="s0:getQuoteHttpGetIn" /> <output message="s0:getQuoteHttpGetOut" /> </operation> </portType> <portType name="StockQuoteServiceHttpPost"> <operation name="getQuote"> <input message="s0:getQuoteHttpPostIn" /> <output message="s0:getQuoteHttpPostOut" /> </operation> </portType> <binding name="StockQuoteServiceHttpGet" type="s0:StockQuoteServiceHttpGet"> <http:binding verb="GET" /> <operation name="getQuote"> <http:operation location="/getQuote" /> <input> <http:urlEncoded /> </input> <output> <mime:mimeXml part="Body" /> </output> </operation> </binding> <binding name="StockQuoteServiceHttpPost" type="s0:StockQuoteServiceHttpPost"> <http:binding verb="POST" /> <operation name="getQuote"> <http:operation location="/getQuote" /> <input> <mime:content type="application/x-www-form-urlencoded" /> </input> <output> <mime:mimeXml part="Body" /> </output> </operation> </binding> Here an element named float is defined to wrap the float result. This style assumes there is a single output message part. Note that although two portTypes are defined here, they are the same. Listing 6 shows a typical response using the float element (see MSgetQuoteResponse.xml). Listing 6. MSStockQuoteService.wsdl HTTP GET or POST Response <?xml version="1.0" encoding="utf-8"?> <float xmlns="http://microsoft.com/webservices/">100</float> As can be seen from these examples, the portType is strongly coupled to the binding extension which prevents portTypes from being reused across different binding extensions. Potential Solutions * Expand the definitions of the binding extensions so they can be applied to any portType. For example, in the HTTP GET or POST bindings, define how the response is generated from a message that has several parts. * Eliminate message definitions and instead define portTypes directly in terms of XML Schema types. Use XPath to bind parts of the schema to the protocol. The binding extension for SOAP is defined in terms of features that interact in a complex way The binding extension for SOAP depends on the following features: * The message part XSD style, either type or element. * The SOAP style, either RPC or Document. * The encoding style, either literal or encoded. * The direction of the message, either input or output. Since each of these four properties has two values, there are a total of sixteen possible combinations. The text of the WSDL 1.1 specification should be clearer about how these properties interact and which combinations are valid since not all seem to be. Each combination should be enumerated and described clearly, and illustrated with an example. It is important to establish the validity and interpretation of each combination in order to improve interoperability between vendors. For example, the current version of WebSphere Studio creates services that use literal encoding in RPC style, but the current version of Microsoft Visual Studio .NET does not support the generation of Web references to that type of service. It is not clear whether this restriction is based on a belief that the combination is not valid, or is simply a prioritization of function delivery. The binding extension for SOAP cannot describe SOAP messages that mix encoding styles at the message part level The SOAP 1.1 specification allows an encodingStyle attribute to be used on any element of a SOAP message (see 4.1.1 SOAP encodingStyle Attribute). For example, each part of a message could be encoded using a different style. In practice, some parts might be SOAP encoded while others are literal. However, in WSDL 1.1, encoding can only be specified at the message level. Therefore WSDL 1.1 cannot accurately describe services that use more than one encoding styles in a single message. The binding extension for HTTP GET or POST does not cover the case of attributes in a complex input type In WSDL 1.1 it is possible to defined an input message part that is a complex XML schema type. For example, Listing 7 shows Person.xsd which defines the complex type PersonType. Listing 7. Person.xsd <?xml version="1.0" encoding="UTF-8"?> <schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.ibm.com" xmlns:Person="http://www.ibm.com"> <complexType name="PersonType"> <sequence> <element name="name" type="string"></element> <element name="birthdate" type="date"></element> </sequence> </complexType> </schema> The WSDL 1.1 specification does not explicitly describe how to URL encode complex types, but a reasonable interpretation is to use the serialized content as a the query string value. For example, suppose an input message has a part named employee of type PersonType. This part would be passed in a query string as: employee=<name>John Doe</name><birthdate>1960-01-01</birthdate> Now suppose that PersonType had an attribute named sex as defined in PersonAttr.xsd which is shown in Listing 8. Listing 8. PersonAttr.xsd <?xml version="1.0" encoding="UTF-8"?> <schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.ibm.com" xmlns:Person="http://www.ibm.com"> <complexType name="PersonType"> <sequence> <element name="name" type="string"></element> <element name="birthdate" type="date"></element> </sequence> <attribute name="sex" type="string"></attribute> </complexType> </schema> How would this be passed in a query string? Clearly the WSDL 1.1 is silent on this topic. The WSDL 1.1 specification should either explicitly disallow attributes, or should define some serialization that can be used with URL encoding, e.g. prefix the content with a comma-separated list of attribute values enclosed in square brackets: employee=[sex(male)]<name>John Doe</name><birthdate>1960-01-01</birthdate> Conclusion The above issues indicate that perhaps the notion of message parts is not flexible enough to achieve the goal of defining portTypes that can be used in different binding extensions. A way out of this problem might be to directly use XML Schema to define the input and output messages of a service and to interpret these schemas as abstract. Certainly XML Schema is expressive enough as a data definition language. Using XML Schema would eliminate any binding-oriented bias that the use of message parts introduces. The problem of defining message parts is then shifted to the binding extension. In the case of SOAP Document binding, the abstract XML Schema definitions can be regarded as concrete. In the case of SOAP RPC, message parts could be defined using XPath expressions. A limited subset of XPath should be adequate for this purpose. Similarly, for HTTP GET and POST, the inputs could be defined using XPath and the output can directly use the XML Schema.
Received on Tuesday, 9 April 2002 03:54:53 UTC