W3C home > Mailing lists > Public > www-ws-desc@w3.org > June 2004

RE: Sample Application described in WSDL using HTTP binding and s howing messages

From: Asir Vedamuthu <asirv@webmethods.com>
Date: Wed, 16 Jun 2004 14:38:53 -0400
Message-ID: <5B10E50E14A4594EB1B5566B69AD94072EF5A4@maileast>
To: 'David Orchard' <dorchard@bea.com>, www-ws-desc@w3.org

David,

I read you posting at,
http://lists.w3.org/Archives/Public/www-ws-desc/2004Jun/0066.html; I have
some comments and will send them in a separate e-mail.

First, some XSD errors,

(a) <xs:element name="Music">
     <xs:complexType name="Music">

This is an anonymous complex type. 'name' attribute is not allowed. This
comment applies to 4 other similar constructs.

(b) some of the element declarations are missing: ArtistID, ArtistFieldName,
ArtistRef, ArtistID, may be more.

Second, WSDL:

(c) I would like to see the WSDL endpoint address. Based on the examples, I
assume that there is a 'Music' segment in the URI path component.

(d) some of the operations are missing: GetArtistList, may be more.

Asir

-----Original Message-----
From: www-ws-desc-request@w3.org [mailto:www-ws-desc-request@w3.org] On
Behalf Of David Orchard
Sent: Wednesday, June 09, 2004 8:12 PM
To: www-ws-desc@w3.org
Subject: Sample Application described in WSDL using HTTP binding and showing
messages



This is potential primer material that explores how to use the WSDL http
binding to describe interactions with an HTTP service.  This is an example
of music information and purchasing Web service.  It is styled after the
CDDB database http://www.gracenote.com/gn_products/cddb.html and
allmusic.com sites.  It has generated a number of questions where I don't
think the WSDL as exists can express certain things.  I'm grateful for any
reviews or comments on this.  It could be put into the primer as well.

An Artist has:
 - ID
 - Name
 - Biography
 - Genre
 - Image
 - Web site

Clients have 3 types of interactions: retrieve all/specific information,
change/add/delete information, and search based upon a subset of the Artist
fields. 

 - Get Artist complete information for a given Artist
 - Get Artist field contents (Name, Biography, etc.) for a given Artist
 - Add Artist
 - Update Artist
 - Get Artist list by Artist name, genre

Schema
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema targetNamespace="http://www.w3.org/2002/ws/music/2004/"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:tns="http://www.w3.org/2002/ws/music/2004/"
elementFormDefault="qualified" attributeFormDefault="unqualified">
  <xs:element name="Music">
    <xs:complexType name="Music">
      <xs:sequence>
        <xs:element ref="tns:Artist" maxOccurs="unbounded"/>
        <xs:element ref="tns:ArtistRef" maxOccurs="unbounded"/>
        <xs:any namespace="##other" processContents="lax"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
  
  <!-- To do a /Music/Artist/5, need to have a type with only 1 child -->
  <xs:complexType name="ArtistIDBase">
    <xs:sequence>
      <xs:element name="id" type="xs:ID"/>
    </xs:sequence>
  </xs:complexType>
  
   <!-- When Adding an artist, the ID isn't known -->
  <xs:element name="ArtistWithoutID">
    <xs:complexType name="ArtistWithoutId">
      <xs:sequence>
        <xs:element name="Name" type="xs:string"/>
        <xs:element name="Biography" type="xs:string"/>
        <xs:element name="Genre" type="xs:string"/>
        <xs:element name="Image" type="xs:anyURI"/>
        <xs:element name="Site" type="xs:anyURI"/>
        <xs:any namespace="##other" processContents="lax"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
  
  <!-- Need to have ID + all of the fields for <artist> returns -->
  <!-- probably better modelling in schema to combine the id with the non-id
fields -->
  <xs:element name="Artist">
    <xs:complexType name="Artist">
      <xs:complexContent>
        <xs:extension base="tns:ArtistIDBase">
          <xs:sequence>
            <xs:element name="Name" type="xs:string"/>
            <xs:element name="Biography" type="xs:string"/>
            <xs:element name="Genre" type="xs:string"/>
            <xs:element name="Image" type="xs:anyURI"/>
            <xs:element name="Site" type="xs:anyURI"/>
            <xs:any namespace="##other" processContents="lax"/>
          </xs:sequence>
        </xs:extension>
      </xs:complexContent>
    </xs:complexType>
  </xs:element>
  
  <!-- Need a query structure to do queries, ie &name=thieverycorp -->
   <xs:element name="ArtistQuery">
    <xs:complexType name="ArtistQuery">
      <xs:complexContent>
        <xs:extension base="tns:ArtistIDBase">
          <xs:sequence>
            <xs:element name="Name" type="xs:string" minOccurs="0"/>
            <xs:element name="Genre" type="xs:string" minOccurs="0"/>
            <xs:element name="Rating" type="xs:decimal" minOccurs="0"/>
          </xs:sequence>
        </xs:extension>
      </xs:complexContent>
    </xs:complexType>
  </xs:element>
  
  <!-- ID + REF structure for getting back list of IDs that can be used to
create URI -->
  <xs:element name="ArtistIDRef">
    <xs:complexType name="ArtistIDRef">
      <xs:complexContent>
        <xs:extension base="tns:ArtistIDBase">
          <xs:sequence>
            <xs:element name="Name" type="xs:string"/>
          </xs:sequence>
        </xs:extension>
      </xs:complexContent>
    </xs:complexType>
  </xs:element>
  
  <!-- Artist Field names for doing field queries -->
  <xs:element name="ArtistIDFieldName" type="tns:ArtistField"/>
  <xs:complexType name="ArtistField">
    <xs:complexContent>
      <xs:extension base="tns:ArtistIDBase">
        <xs:sequence>
          <xs:element name="Field" type="tns:ArtistFieldNames"/>
        </xs:sequence>
      </xs:extension>
    </xs:complexContent>
  </xs:complexType>
  
  <!-- Artist Field Name + Value for setting field -->
  <xs:element name="ArtistFieldNameAndValue">
    <xs:complexType name="ArtistFieldNameAndValue">
      <xs:complexContent>
        <xs:extension base="tns:ArtistField">
          <xs:sequence>
            <xs:element name="Value"/>
          </xs:sequence>
        </xs:extension>
      </xs:complexContent>
    </xs:complexType>
  </xs:element>
  
  <!-- List of field names -->
  <xs:simpleType name="ArtistFieldNames">
    <xs:restriction base="xs:string">
      <xs:enumeration value="Name"/>
      <xs:enumeration value="Biography"/>
      <xs:enumeration value="Genre"/>
      <xs:enumeration value="Image"/>
      <xs:enumeration value="Site"/>
    </xs:restriction>
  </xs:simpleType>
  
  <!-- URI for getting back opaque URIs -->
  <xs:complexType name="uri">
    <xs:sequence>
      <xs:element name="uri" type="xs:anyURI"/>
    </xs:sequence>
  </xs:complexType>
</xs:schema>



Interacting using the x-www-form-uriencoded style
WSDL

<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions xmlns:musicw="http://example.com/Artist" xmlns:wsdl="">
	<xs:import href="Music-Artist.xsd"/>
	<wsdl:interface name="Artist">
		<wsdl:operation name="ArtistSearch" method="GET">
			<wsdl:input ref="music:ArtistQuery"/>
			<wsdl:output ref="music:Music"/>
		</wsdl:operation>
		<wsdl:operation name="ArtistRefSearch" method="GET">
			<wsdl:input ref="music:ArtistQuery"/>
			<wsdl:output ref="music:Music"/>
		</wsdl:operation>
		<wsdl:operation name="GetArtist" method="GET">
			<wsdl:input ref="music:ArtistID"/>
			<wsdl:output ref="music:Artist"/>
		</wsdl:operation>

		<!-- Given a uri in a field for an artist, simply
dereference the URI -->
		<wsdl:operation name="GetArtistOpaqueURI" method="GET">
			<wsdl:input ref="music:uri"/>
			<wsdl:output ref="music:ArtistWithoutURI"/>
		</wsdl:operation>
		
		<wsdl:operation name="GetFieldByFieldName" method="GET">
			<wsdl:input ref="music:ArtistFieldName"/>
			<wsdl:output ref="xsd:any"/>
		</wsdl:operation>
		<wsdl:operation name="AddArtistServerID" method="POST">
		   <wsdl:input ref="music:ArtistWithoutID"/>
		   <wsdl:output ref="music:ArtistRef"/>
		 </wsdl:operation>	 
		 <wsdl:operation name="AddArtistClientID" method="POST">
		   <wsdl:input ref="music:Artist"/>
		   <wsdl:output ref="music:ArtistRef"/>
		 </wsdl:operation>
		<wsdl:operation name="DeleteArtist" method="DELETE">
			<wsdl:input ref="music:ArtistID"/>
		</wsdl:operation>
		<wsdl:operation name="UpdateArtist" method="PUT">
			<wsdl:input ref="music:Artist"/>
			<wsdl:output ref="music:Artist"/>
		</wsdl:operation>
		<wsdl:operation name="UpdateField" method="PUT">
			<wsdl:input ref="music:ArtistFieldNameAndValue"/>
		</wsdl:operation>

	</wsdl:interface>
	<wsdl:binding name="Artist" interface="Artist"
http:defaultMethod="GET">
	<wsdl:operation ref="ArtistSearch" location="Artist/{Name}"/>
	<wsdl:operation ref="ArtistRefSearch" location="ArtistRef/{Name}"/>
  	<wsdl:operation ref="GetArtist" location="Artist/{ID}"/>
  	<wsdl:operation ref="GetArtistOpaqueURI" location="{uri}"/>
  	<wsdl:operation ref="GetFieldByFieldname" location="Artist/{ID}/"/>
  	<wsdl:operation ref="AddArtistServerID" location="Artist"
method="POST"/>
 	<wsdl:operation ref="AddArtistClientID" location="Artist"
method="POST"/>
  	<wsdl:operation ref="DeleteArtist" location="Artist/{ID}"
method="DELETE"/>
  	<wsdl:operation ref="UpdateArtist" location="Artist/{ID}"
method="PUT"/>
  	<wsdl:operation ref="UpdateArtistField" location="Artist/{ID}"
method="PUT"/>
	</wsdl:binding>
</wsdl:definitions>

Message Examples

Example: ArtistSearch 
GET /Music/Artist?genre="electronica"

Return:
<Music>
  <Artist>
    <ID>5</ID>
    <Name>Thievery Corp</Name> 
    <Genre>Electronica</Genre>
    <site>http://thievery.com</site>
  </Artist>
</Music>

Example: GetAllArtists
GET /Music/Artist

Returns:
<Music>
  <Artist>
    <ID>5</ID>
    <Name>Thievery Corp</Name>
    <Genre>Electronica</Genre>
    <site>http://thievery.com</site>
  </Artist>
</Music>

Example: GetArtistReferences
GET /Music/ArtistRef?genre="electronica"

Return:
<Music>
  <ArtistRef>
    <ID>5</ID>
    <Name>Thievery Corp</Name> 
  </ArtistRef>
</Music>

Example: GetArtist 
GET /Music/Artist/5

Return:
<Artist>
  <ID>5</ID>
  <Name>Thievery Corp</Name>
  <Genre>Electronica</Genre>
  <site>http://thievery.com</site>
</Artist>

Example: GetArtistOpaqueURI
* This assumes the URI="id/xyz"
GET /Music/Artist/id/zyz

Return:
<Artist>
  <Name>Thievery Corp</Name>
  <Genre>Electronica</Genre>
  <site>http://thievery.com</site>
</Artist>


Example: GetFieldByFieldName
GET /Music/Artist/5?field="site"

Return:
<site>http://thievery.com</site>

Example: AddArtistServerId
POST /Music/Artist
<Artist>
    <Name>Thievery Corp version 2</Name>
    <Genre>Electronica</Genre>
    <site>http://newbetterthievery.com</site>
</Artist>

Returns:
Content-Location: /Music/Artist/6
* How is the HTTP Content-location mapped to xml in this case?  Is it
dropped?  Should there be XML returned?

Example: AddArtistClientID
* I don't think this works in the current WSDL http binding
POST /Music/Artist/7
<Artist>
    <ID>7</ID>
    <Name>Thievery Corp version 3</Name>
    <Genre>Electronica</Genre>
    <site>http://newwaybetterthievery.com</site>
</Artist>

Returns:
Content-Location: /Music/Artist/7

Example: DeleteArtist
DELETE /Music/Artist/5

Example: UpdateArtist
* I don't think this works in the current WSDL http binding
PUT /Music/Artist/5
<Artist>
    <ID>5</ID>
    <Name>Thievery Corp</Name>
    <Genre>Electronica</Genre>
    <site>http://newbetterthievery.com</site>
  </Artist>

Example: UpdateArtistField
* I don't think this works in the wsdl as is
PUT /Music/Artist/5/site
<site>http://newbetterthievery.com</site>
Received on Wednesday, 16 June 2004 14:42:14 GMT

This archive was generated by hypermail 2.2.0+W3C-0.50 : Monday, 7 December 2009 10:58:31 GMT