It's finally time for me to push out my thoughts on *the one* Web description language. I offer WDL, the Web Description Language. (Note: I had thought of calling it "DEREST" for DEscribing REST and combining with Rohit's "ARREST" so we could talk about "DEARREST" :-) I also provide a descriptions page that links to a lot of other description formats around Web formats.

The most common cases of Web applications, GETting and POSTing XML Documents, should be as simple as possible.

WSDL 2.0 provides mechanisms for describing Web applications. It embodies 2 fundamental design choices: that an interface, consisting of operations, is re-usable across multiple bindings; and each of these bindings is re-usable across multiple endpoints.

WDL targets a different design center. Operations can be defined and then associated with resources. It allows inlining of operations to resources. It re-uses WSDL 2.0's re-use of Schema, definition of operations, URI construction syntax, configuration of HTTP Parameters.

Yahoo Search sample

The Yahoo search service is used as an example, and I've provided a Yahoo WSDL 2.0 sample. Marc Hadley also used Yahoo's news search for his WADL

<?xml version="1.0" encoding="UTF-8"?> <wdl:resources xmlns:ysearchtypes="http://www.pacificspirit.com/ns/2005/yahoo/srch/types/" xmlns:yahoowns="http://www.pacificspirit.com/ns/2005/yahoo/srch/" targetNamespace="http://www.pacificspirit.com/ns/2005/yahoo/srch/" xmlns:wdl="http://www.w3.org/2004/08/wsdl" xmlns:yahoosrch="urn:yahoo:srch" xmlns:xs="http://www.w3.org/2001/XMLSchema"> <xs:import namespace="http://www.pacificspirit.com/ns/2005/yahoo/srch/types/" location="./YahooV1Search.xsd"/> <xs:import namespace="urn:yahoo:srch" location="./YahooV1SearchFault.xsd"/> <xs:import namespace="urn:yahoo:srch" location="http://api.search.yahoo.com/WebSearchService/V1/WebSearchResponse.xsd"/> <!-- http://api.search.yahoo.com/WebSearchService/V1/webSearch?appid=YahooDemo&query=madonna&results=2 --> <wdl:resource location="http://api.search.yahoo.com/WebSearchService/V1/"> <wdl:getoperation location="{searchString}"> <wdl:output ref="yahoosrch:Result"/> <wdl:output code="400 403 503" ref="yahoosrch:Error"/> </wdl:operation> </wdl:resource> </wdl:resources>

Available at Yahoo.wdl

Design Decisions

Some design decisions worth noting:

  1. Generative identifiers: The uri path is defined by the instance content of a schema type, like WSDL 2.0. Other specifications like WADL and NSDL use a request structure that contains each of the parameters. This feels to me like the badness that was WSDL 1.1's parts construct.
  2. URI-Operation relationship: The resources elements contain operation elements. Most other specifications use references for associating URIs with operations. There is little value in re-using operations, given the generative identifiers provided.
  3. Associating schema with types and XPath: No provision is made for "parameterizing" inputs or outputs. Arthur Ryman made a parameterizing in WSDL 2.0 proposal in April 2003, and WADL and NSDL have taken up that feature.
  4. Parameter overloading: multiple inputs, outputs(including faults) per operation may be specified. These are taken to be equivalent for a given operation. It is possible to have multiple operations using the same HTTP verb for a location to associate an input with specific outputs and/or faults.
  5. Media Types. May be specified for inputs and outputs, and uses the WSDL/XMLP work on describing binary media types in xml.
  6. Faults: similar to WSDL 2.0 Fault description with type, code, and headers.
  7. HTTP Headers: identifiable by qnames in the inputheader or outputheader attributes.
  8. HTTP Status Codes: The default for outputs is 2xx and for faults is 4xx/5xx. The specific codes can be set in the output element
  9. HTTP Configuration: authentication, transfer-coding, version are all settable on the operation.

Component Description

WDL is primarily a list of resources. The schema types are imported. A resource is defined for a location. An operation on that URI, with an HTTP method and optional location refinement. The input, output, and fault elements for the operation are defined.


<?xml version="1.0" encoding="UTF-8"?> <wsd:resources ... > <xs:import/>? <xs:include/>? <wsd:resource location="xs:anyURI" authenticationType="xs:string"? authenticationRealm="xs:string"? httpVersion="xs:int"? ...> <wsd:operation method="xs:string" location="xs:string" ...>* <wsd:input ref="xs:QName"? mediaType="xs:anyURI" transferCoding="xs:string"? ...>* <wsd:header headerName="xs:string" ref="xs:Qname"/>* <wsd:output code="xs:integer (xs:integer )*"? ref="xs:QName" mediaType="xs:anyURI" transferCoding="xs:string"?...> <wsd:header headerName="xs:string" ref="xs:Qname"/>* </wsd:operation> <wsd:getoperation location="xs:string" ...>* <wsd:input ...>? <wsd:header headerName="xs:string" ref="xs:Qname"/>* <wsd:output code="xs:integer (xs:integer )*"? ref="xs:QName" mediaType="xs:anyURI" transferCoding="xs:string"?...> <wsd:header headerName="xs:string" ref="xs:Qname"/>* </wsd:operation> </wsd:resource> </wsd:resources>

The following are descriptions and additional normative constraints on the template listed above

Normative Schema

Avaiable at WDL.xsd

<?xml version="1.0" encoding="UTF-8"?> <xs:schema targetNamespace="http://www.pacificspirit.com/ns/2005/05/WDL/" xmlns:tns="http://www.pacificspirit.com/ns/2005/05/WDL/" xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified"> <xs:element name="resources"> <xs:complexType name="resourcesType"> <xs:sequence> <xs:any namespace="##other" processContents="lax" maxOccurs="unbounded"/> <xs:element ref="tns:resource" maxOccurs="unbounded"/> <xs:any namespace="##other" processContents="lax" maxOccurs="unbounded"/> </xs:sequence> </xs:complexType> </xs:element> <xs:element name="resource"> <xs:complexType name="resourceType"> <xs:choice> <xs:element ref="tns:operation"/> <xs:element ref="tns:getoperation"/> <xs:any namespace="##other" processContents="lax"/> </xs:choice> <xs:attribute name="location" type="xs:anyURI"/> <xs:attribute name="authenticationType" type="xs:string"/> <xs:attribute name="authenticationRealm" type="xs:string"/> <xs:attribute name="httpVersion" type="xs:string"/> </xs:complexType> </xs:element> <xs:element name="operation"> <xs:complexType name="operationType"> <xs:sequence> <xs:element ref="tns:input" maxOccurs="unbounded"/> <xs:element ref="tns:output" maxOccurs="unbounded"/> <xs:any namespace="##other" processContents="lax"/> </xs:sequence> <xs:attribute name="method" type="xs:string"/> <xs:attribute name="location" type="xs:string"/> </xs:complexType> </xs:element> <xs:element name="input"> <xs:complexType name="inputType"> <xs:sequence> <xs:element ref="tns:header" minOccurs="0" maxOccurs="unbounded"/> </xs:sequence> <xs:attribute name="ref" type="xs:QName"/> <xs:attribute name="transferCoding" type="xs:string"/> </xs:complexType> </xs:element> <xs:element name="output"> <xs:complexType name="outputType"> <xs:sequence> <xs:element ref="tns:header" minOccurs="0" maxOccurs="unbounded"/> </xs:sequence> <xs:attribute name="code" type="xs:string"/> <xs:attribute name="ref" type="xs:QName"/> <xs:attribute name="transferCoding" type="xs:string"/> </xs:complexType> </xs:element> <xs:element name="header"> <xs:complexType name="headerType"> <xs:sequence/> <xs:attribute name="headerName" type="xs:string"/> <xs:attribute name="ref" type="xs:QName"/> </xs:complexType> </xs:element> <xs:element name="getoperation"> <xs:complexType name="operationType"> <xs:sequence> <xs:element ref="tns:output" minOccurs="1" maxOccurs="unbounded"/> <xs:any namespace="##other" processContents="lax"/> </xs:sequence> <xs:attribute name="method" type="xs:string" use="prohibited"/> <xs:attribute name="location" type="xs:string"/> </xs:complexType> </xs:element> </xs:schema>