"The description language SHOULD allow describing Messages that include references (URIs) to strongly-typed referents, both values and Services. (From PP. Last discussed 11 April, 2002.)"R085 is based on the note WSDL Requirements which was posted to the public mailing list by Paul Prescod on Fri, Feb 15 2002. This requirement means that if the URI of a Web service is passed in a message, then the WSDL should specify the interface and binding supported by that URI.
WSDL 1.1 does not satisfy R085 because messages are only described as data types, e.g. using XML Schema. If a message contains a Web service URI then the best WSDL 1.1 can do is to describe it as the XML Schema simple type anyURI. There is no way in WSDL 1.1 to describe the URI as being the endpoint of a Web service that implements a specific binding for an interface. This document proposes a way to satisfy R085 in WSDL 1.2.
In some cases a URI in not sufficient to identify a Web service endpoint. For example, the recent WS-Addressing specification provides an XML complex type, wsa:EndpointReferenceType, that includes a URI (in a wsa:Address child element, and additional optional information. The proposed solution is applicable both to the case of simple URIs and to other more complex formats such as wsa:EndpointReferenceType. However, since WS-Addressing is currently not a standard, the WSDL 1.2 specification cannot normatively reference it. Here it is used as an example of a format that provides a richer description of Web service endpoints. If WS-Addressing becomes a standard, then the WSD Working Group should consider adding a normative reference to it.
There are two main levels of Web service type information in WSDL 1.2, interface and binding. An interface describes an abstract set of operations which are subsequently bound to a concrete protocol by a binding. The separation of Web service type information into interface and binding levels is intended to simplify the description of Web services that implement a given interface over multiple bindings.
A Web service URI is the endpoint for some binding. In the following, I'll refer to a Web service URI and optional additional information that is passed in a message as an endpoint reference. The proposed solution is:
Consider the example described in Building Web Services the REST Way by Roger L. Costello. Here we have a fictious company, Parts Depot, Inc., that has Web services to list parts, get part information, and submit purchase orders. The part list Web service is located at:
We can send it an HTTP GET request to receive the following XML document which lists the parts available for purchase:http://www.parts-depot.com/parts
<?xml version="1.0"?>This message contains URIs that refer to the parts that are available for purchase. Note that the URIs are included as hyperlinks using XLink, which is the recommended way to implement hyperlinking in XML documents. Each part is a resource and can be viewed as the endpoint of a Web service since it also responds to messages. For example, part #00345 has the URI
<p:Parts xmlns:p="http://www.parts-depot.com"
xmlns:xlink="http://www.w3.org/1999/xlink">
<Part id="00345" xlink:href="http://www.parts-depot.com/parts/00345"/>
<Part id="00346" xlink:href="http://www.parts-depot.com/parts/00346"/>
<Part id="00347" xlink:href="http://www.parts-depot.com/parts/00347"/>
<Part id="00348" xlink:href="http://www.parts-depot.com/parts/00348"/>
</p:Parts>
http://www.parts-depot.com/parts/00345We can send an HTTP GET to this URI and receive the following XML document which describes part #00345 in detail:
<?xml version="1.0"?>In this example, the part list only contains a few entries, but in practice it could contain thousands. Furthermore, the part list is likely to change as new parts become available and old part become obsolete. It is therefore neither useful nor practical to describe each part Web service using a WSDL <service> element in some document. Instead, the part list Web service is the best solution, provided that we can describe it accurately in WSDL 1.2.
<p:Part xmlns:p="http://www.parts-depot.com"
xmlns:xlink="http://www.w3.org/1999/xlink">
<Part-ID>00345</Part-ID>
<Name>Widget-A</Name>
<Description>This part is used within the frap assembly</Description>
<Specification xlink:href="http://www.parts-depot.com/parts/00345/specification"/>
<UnitCost currency="USD">0.10</UnitCost>
<Quantity>10</Quantity>
</p:Part>
The part list Web service would likely have other operations, for example to filter the list of parts returned. Each part Web service would also have other operations, for example to change the quantity avaliable. However, for the purpose of illustration, these other operations add no new insight and will therefore not be discussed further.
The part Web service has the following description. First consider the part service:
<wsdl:message name="getPartInput"/>Here we define a single operation that returns the detailed part information. Note that there is no <service> element for the part service since we plan to return the endpoints in the response from the part list service. Now consider the part list service:
<wsdl:message name="getPartOutput">
<wsdl:part name="return" element="p:Part"></wsdl:part>
</wsdl:message><wsdl:interface name="partInterface">
<wsdl:operation name="GET">
<wsdl:input message="tns:getPartInput"/>
<wsdl:output message="tns:getPartOutput"/>
</wsdl:operation>
</wsdl:interface><wsdl:binding name="partHTTPBinding" type="tns:partInterface">
<http:binding verb="GET"/>
<wsdl:operation name="GET">
<http:operation location=""/>
<wsdl:input>
<http:urlEncoded/>
</wsdl:input>
<wsdl:output>
<mime:mimeXml part="return"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:message name="getPartListInput"/>Here we include a <service> element to provide the address of the part list service. The endpoint reference information is described in two places. The part list interface definition contains an endpoint reference definition at line [1]. The endpoint reference definition defines the position of the Web service URIs within the message. The definition associates the part Web service interface with these URIs. The part list binding definition uses this endpoint reference definition at line [2] and assocates the part HTTP binding with it.
<wsdl:message name="getPartListOutput">
<wsdl:part name="return" element="p:Parts"/>
</wsdl:message><wsdl:interface name="partListInterface">
<wsdl:operation name="GET">
<wsdl:input message="tns:getPartListInput">
<wsdl:output message="tns:getPartListOutput">
[1] <wsdl:endpoint name="partURI" part="return" xpath="/p:Parts/Part/@xlink:href" interface="tns:partInterface"/>
</wsdl:output>
</wsdl:operation>
</wsdl:interface><wsdl:binding name="PartListHTTPBinding" type="tns:partListInterface">
<http:binding verb="GET"/>
<wsdl:operation name="GET">
<http:operation location=""/>
<wsdl:input>
<http:urlEncoded/>
</wsdl:input>
<wsdl:output>
[2] <wsdl:endpoint name="partURI" binding="tns:partHTTPBinding"/>
<mime:mimeXml part="return"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding><wsdl:service name="PartListService">
<wsdl:port name="PartListHTTPPort" binding="tns:PartListHTTPBinding">
<http:address location="http://www.parts-depot.com/parts"/>
</wsdl:port>
</wsdl:service>
<?xml version="1.0"?>This message contains URIs that refer to the parts that are available for purchase. Note that the URIs are included as wsa:Address content within wsa:EndpointReference elements. WS-Addressing optionally allows the interface information to be sent, but in this example the interface QName has a fixed value and we describe it in the WSDL document for the service rather than send it with the message.
<p:Parts xmlns:p="http://www.parts-depot.com"
xmlns:wsa="http://schemas.xmlsoap.org/ws/2003/03/addressing">
<Part id="00345">
<wsa:EndpointReference>
<wsa:Address>http://www.parts-depot.com/parts/00345</wsa:Address>
</wsa:EndpointReference>
</Part>
<Part id="00346">
<wsa:EndpointReference>
<wsa:Address>http://www.parts-depot.com/parts/00346</wsa:Address>
</wsa:EndpointReference>
</Part>
<Part id="00347">
<wsa:EndpointReference>
<wsa:Address>http://www.parts-depot.com/parts/00347</wsa:Address>
</wsa:EndpointReference>
</Part>
<Part id="00348">
<wsa:EndpointReference>
<wsa:Address>http://www.parts-depot.com/parts/00348</wsa:Address>
</wsa:EndpointReference>
</Part>
</p:Parts>
Now consider the part list service:
<wsdl:message name="getPartListInput"/>Here the value of the xpath expression in [1] is a list of nodes of type wsa:EndpointReferenceType instead of simply xsd:anyURI. In general for WS-Addressing, the xpath expression evaluates to a list of nodes that are of type wsa:EndpointReferenceType, or a type that derives from it.
<wsdl:message name="getPartListOutput">
<wsdl:part name="return" element="p:Parts"/>
</wsdl:message><wsdl:interface name="partListInterface">
<wsdl:operation name="GET">
<wsdl:input message="tns:getPartListInput">
<wsdl:output message="tns:getPartListOutput">
[1] <wsdl:endpoint name="partURI" part="return" xpath="/p:Parts/Part/wsa:EndpointReference" interface="tns:partInterface"/>
</wsdl:output>
</wsdl:operation>
</wsdl:interface><wsdl:binding name="PartListHTTPBinding" type="tns:partListInterface">
<http:binding verb="GET"/>
<wsdl:operation name="GET">
<http:operation location=""/>
<wsdl:input>
<http:urlEncoded/>
</wsdl:input>
<wsdl:output>
[2] <wsdl:endpoint name="partURI" binding="tns:partHTTPBinding"/>
<mime:mimeXml part="return"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding><wsdl:service name="PartListService">
<wsdl:port name="PartListHTTPPort" binding="tns:PartListHTTPBinding">
<http:address location="http://www.parts-depot.com/parts"/>
</wsdl:port>
</wsdl:service>