- From: Mark Baker <mbaker@idokorro.com>
- Date: Thu, 27 Mar 2003 21:35:01 -0500
- To: "Arthur Ryman" <ryman@ca.ibm.com>
- Cc: <www-ws-desc@w3.org>, <www-ws-desc-request@w3.org>
-----Original Message----- From: Arthur Ryman [mailto:ryman@ca.ibm.com] Sent: Thursday, March 27, 2003 6:08 PM To: Mark Baker Cc: www-ws-desc@w3.org; www-ws-desc-request@w3.org Subject: RE: Thoughts on urlReplacement, REST, and R085 Mark, Thx for the feedback. In a separate piece of work Philippe and I have revised the HTTP binding for WSDL 1.2. In WDSL 1.1 the HTTPbinding used either GET or POST for all the operations, which is of course wrong wrt REST. The revision allows you to specify the HTTP verb on a per operation basis. Philippe will post this soon. Pls comment on that when it appears. SOAP 1.2 only specifies GET and POST, not the other HTTP verbs, allow it leaves this possibility open. I think there is value is using the other verbs but I personally could use some guidance on their semantics. For example, to create a new Part at Part Depot, what should I do? Should I POST a Part document to the part list URI, or should I PUT a Part document to a new part URI? Also, technically, a purist might say that my Update Quantity example was a hack since I should really PUT and new Part document (or subset of one) to the Part URI instead of POSTing. When I DELETE, am I deleting from the Part List URI or do I send a DELETE to the Part URI? I think we could make progress on the other verbs if there was a shared understanding of their intended semantics. At present, we have at least established that GET should be side-effect free to enable caching. Perhaps we could adopt the semantics for the verbs defined by WebDAV? I understand the point about uniform interface, and I think we are not really inconsistent here. In my example below, I call the operation getPartDetail, but that is really just documentation for the reader. That verb does NOT appear on the URI. Consider queries we might make on the part list. If I do an unqualified GET, I receive the entire state of the list. But maybe if the list if huge, the server will rightly refuse to send it, and instead sends me a failure response. What I should do is a GET that filters the result by some criteria. For example, I could define a getByIdRange operation in WSDL like this: <message name="getByIdRangeInput"> <part name="lowerId" type="xsd:string"/> <part name="upperId" type="xsd:string"/> </message> <portType name="partDetailInterface"> <operation name="getByIdRange"> <input message="tns:getByIdRangeInput"/> <output message="tns:getPartListOutput"/> </operation> .... </portType> I invoke the operation like: http://www.part-depot.com/parts?lowerId=00300&upperId=00500 So we are still using the GET verb, but we are documenting the semantics of the query parameters in the WSDL and giving the operation a meaningful name. If this was Smalltalk, the operation would be named something like GET:lowerId:upperId, i.e. the formal parameter names get concatenated together to form a method name. GET is like an overloaded method in C++, Java, etc. The unfiltered and filtered operations have the following signatures: PartList GET( ); PartList GET(String lowerId, String upperId); In WSDL we decided to avoid overloading, so we need to assign unique names to the operations. For HTTP, the names don't necessarily appear in the message. However, the names are still useful when it comes to code generation, e.g. the above operations get mapped to: PartList getPartList( ); PartList getByIdRange(String lowerId, String upperId); So circling back to your suggestion, I think it would be useful to add information to the operation to indicated its semantics (e.g. create/delete/update/retrieve, aka CRUD), but this is independent of HTTP since the operation definition is abstract. The semantic hint could be used to select the proper HTTP verb in the HTTP binding and the SOAP/HTTP binding. For example, delete/create/update might collapse unto POST for SOAP/HTTP. Arthur Ryman "Mark Baker" <mbaker@idokorro.com> Sent by: www-ws-desc-request@w3.org 03/27/2003 02:23 PM To: "Arthur Ryman" <ryman@ca.ibm.com>, <www-ws-desc@w3.org> cc: Subject: RE: Thoughts on urlReplacement, REST, and R085 Right on, Arthur. I just have one minor disagreement with it though, where you say that you believe that satisfying R085 will suffice to address this deficiency. While I believe that satisfying R085 is necessary, I don't believe it is sufficient, as I also believe that issue 64 must be addressed, perhaps with a solution that I proposed in [1] and [2]. The reason I believe this, is that the semantics of a WSDL operation (e.g. "getPartDetail" in the example you provided) is no longer part of the interface published by the server when GET is used (i.e. clients aren't required to know what it means). So just satisfying R085 would leave WSDL in a state where sometimes operation names are part of the interface, and sometimes not. My proposal to expose GET, PUT, POST, etc.. as WSDL operation names would address this. Does that make sense? Thanks. BTW, apologies in advance for future tardy followups, as I'm only able to get email sporadically while I endure the painful process of switching ISPs. 8-{ [1] http://lists.w3.org/Archives/Public/www-ws-desc/2003Jan/0103 <http://lists.w3.org/Archives/Public/www-ws-desc/2003Jan/0103> [2] http://lists.w3.org/Archives/Public/www-ws-desc/2003Jan/0111 <http://lists.w3.org/Archives/Public/www-ws-desc/2003Jan/0111> MB -----Original Message----- From: Arthur Ryman [mailto:ryman@ca.ibm.com] Sent: Thursday, March 27, 2003 10:50 AM To: www-ws-desc@w3.org Subject: 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 21:35:03 UTC