Thoughts on urlReplacement, REST, and R085

I took an action item on 2003-02-13 to look at urlReplacement and to 
determine if it was adequate for REST style Web services. My conclusion is 
that urlReplacement is syntactically expressive enough to describe the 
type of URIs employed, but its use raises architectural concerns. Consider 
the example described in "Building Web Services the REST Way" by  Roger L. 
Costello [1]. 
In this example, there is a Web application at the fictious company "Parts 
Depot, Inc." that allows you to obtain a list of parts, get detailed 
information about a specific part, and submit a purchase order . 
To obtain the part list, send an HTTP GET to:
http://www.parts-depot.com/parts
You receive the following XML document:
<?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>

To obtain the detail on part 00345, send an HTTP GET:
http://www.parts-depot.com/parts/00345

You receive the following XML document:

<?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 we have 5 URI's: 1 for the part list and 4 for the parts. 
How many Web services do we have? In [1] the view is that we have two, one 
for the part list and one for all the parts. 

Consider the part detail service. If we only have the GET operation 
described here, then WSDL 1.1 urlReplacement is adequate to describe the 
service., e.g.

<message name="partDetailInput">
        <part name="id" type="xsd:string"/>
<message/>

<message name=partDetailOutput">
        <part name="return" element="tns:PartDetail"/>
</message>

<portType name="partDetailInterface">
        <operation name="getPartDetail">
                <input message="tns:partDetailInput"/>
                <output message="tns:partDetailOutput"/>
        </operation>
</portType>

<binding name="partDetailHttp" type="tns:partDetailInterface">
        <http:binding verb="GET"/>
        <operation name="getPartDetail">
                <http:operation location="(id)"/>
                <input>
                        <http:urlReplacement/>
                </input>
                <output>
                        <mime:mimeXml part="return"/>
                </output>
        </operation>
</binding>

<service name="partDetailService">
        <port name="partDetailPort" binding="tns:partDetailHttp>
                <http:address 
location="http://www.part-depot.com/parts/"/>
        </port>
</service>

However, this approach breaks down if we add another operation, say one to 
update the part detail, using POST. Although we can't combine GET and POST 
in the same binding in WSDL 1.1, this is an accepted requirement for WSDL 
1.2. Let's assume we have an updateQuantity operation which has the 
following input message:

<message name="updateQuantityInput">
        <part name=id" type=xsd:string"/>
        <part name="quantity" type="xsd:int"/>
</message>

We have a problem now because we need to bind the id to the url using 
urlReplacement and the quantity to the message body using mimeXml. But 
urlReplacement and mimeXml are mutually exclusive in WSDL 1.1. We could 
simply revise the binding in WSDL 1.2 to allow this, but then we run into 
another conceptual problem.

Consider the output of the part list. It contains URIs for the parts, e.g. 
http://www.part-depot.com/parts/00345. This URI is something we can send 
messages to and get responses back from so it is natural to regard it as 
the endpoint of a Web service. But in our example we are not treating each 
part as a Web service. We are treating the set of all the parts as a 
single Web service, i.e. the part detail Web service.

I suggest that it is natural to regard each part as a Web service 
endpoint. The part id is then encoded in the address of the Web service 
and is not treated as an input parameter to a Web service operation. We 
therefore have one Web service for the part list and one Web service for 
each part. Now it is of course non-sensical to have a WSDL <service> 
element for each part since the set of parts is more likely to be 40,000 
than 4. In practice, the part list would be dynamic with parts being added 
and removed. Therefore there must be another way to publish the URIs for 
the parts. The answer is in improving the description of the part list 
service to include the information that identifies the URIs are being Web 
service endpoints. This is requirement R085. A client of the part detail 
Web service discovers the part URIs via the part list Web service, and not 
via <service> elements in WSDL documents.

In conclusion, the current urlReplacement mechanism is inadequate in 
practice and is inconsistent with REST since it obscures the role of URIs. 
IMHO, the correct resolution of this problem lies in satisfying R085.

[1] http://www.xfront.com/REST-Web-Services.html

Arthur Ryman

Received on Thursday, 27 March 2003 10:50:15 UTC