Web Services Description R085: Describing Messages That Refer to Web Services

Arthur Ryman
2003-04-22

Introduction

Hyperlinking is a cornerstone of the Web, so it is natural to extend this concept to Web services. Hyperlinking in Web services means that Web service messages can refer to other Web services. There are many cases in which it is useful for a Web service message to contain references to other Web services. For example: In view of these many uses, it is important for WSDL 1.2 to be capable of describing Web service messages the refer to other Web services. This requirement is included in Web Service Description Requirements as R085:
"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.

Proposed Solution

As mentioned above, messages can already include URIs and these can be described as data types, e.g. using the XML Schema simple type wsd:anyURI or, e.g., the complex type wsa:EndpointReferenceType. R085 is satisified if we can associate the Web service interface and binding with the URI.

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:

  1. to define endpoint references and describe their Web service interfaces in the description of the Web service's interface, and
  2. to describe their bindings in the description of the Web service's binding.

XLink Example

An example will serve to illustrate this proposal.

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:

http://www.parts-depot.com/parts
We can send it an HTTP GET request to receive the following XML document which lists the parts available for purchase:
<?xml version="1.0"?>
<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>
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
http://www.parts-depot.com/parts/00345
We can send an HTTP GET to this URI and receive the following XML document which describes part #00345 in detail:
<?xml version="1.0"?>
<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>
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.

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"/>
<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>

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="getPartListInput"/>
<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>

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.

WS-Addressing Example

For comparison, the above example is reformulated using WS-Addressing. We can send the part list service an HTTP GET request to receive the following XML document which lists the parts available for purchase:
<?xml version="1.0"?>
<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>
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.

Now consider the part list service:

<wsdl:message name="getPartListInput"/>
<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>

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.

Specification of <wsdl:endpoint>

Endpoint Reference Interface Description

An endpoint reference interface description may appear as an immediate child of <wsdl:input>, <wsdl:output>, or <wsdl:fault> within a <wsdl:interface> element. The parent of the <wsdl:endpoint> element associates a <wsdl:message> element with it. The <wsdl:enpoint> element has the following attributes:

Endpoint Reference Binding Description

An endpoint reference binding description may appear as an immediate child of <wsdl:input>, <wsdl:output>, or <wsdl:fault> within a <wsdl:binding> element. The <wsdl:endpoint> element has the following attributes:

Conclusion

The ability to describe messages that contain endpoints references is a recognised and important requirement for WSDL 1.2. This proposal satifies the requirement through the addition of a mechanism to endpoint reference interfaces as part of the interface definition, and to bind them as part of the binding definition in a manner that is both consistent with the current WSDL binding design and that introduces a minimum of additional concepts to the WSDL abstract model.