NUN.ME.SHU banner
Switch to normal page layoutNun.Me.Shu - web services

Overview of how XML/HTTP web services are implemented in the Nun.Me.Shu framework, with special focus on the implementation of Amazon.com's XML/HTTP web service.



XML/HTTP web services introduction
The term "XML/HTTP web services" is used to identify applications that send XML data in respons to an HTTP request. It involves the use of standard HTTP URLs with specific name/value pairs to invoke methods and processes within a third-party's Web Services framework. The URL is the primary method used for message passing. Once the URL is processed by the web service, a well-formatted XML document is returned over HTTP as a response.
XML/HTTP is sometimes refered to as REST (REpresentational State Transfer)New page displays in separate browser window. However, this is not really correct in my opinion; REST is much more than just XML/HTTP. REST is a fairly abstract architectural style, characterized by a uniform connector interface. As such, XML/HTTP can be seen as an example of a REST implementation. But then again, the whole modern Web is an instance of a REST-style architecture.
Note that there are also "XML/SOAP web services". SOAP (Simple Object Access Protocol) was developed to deal with the limitations of XML/HTTP. SOAP is a lightweight protocol, using XML technologies to define a messaging framework intended for exchanging structured information in a decentralized, distributed environment.

In the case of Amazon.com, the leading Internet e-tailer; its web service allows other sites to interact with Amazon's catalog, search engine, shopping cart and merchandising tools. Instead of simply linking to Amazon's various products, web sites can embed search results, top sellers, customized lists, recommendations, and even the Amazon shopping cart within their applications. The first web services that Amazon.com has exposed are:
° Product Display – The ability to search for and retrieve product information from the Amazon.com catalog.
° Shopping Cart – The ability to add Amazon.com products to shopping carts, wish lists, and registries from third party locations.
See an implementation of this at work on my store page.


XML/HTTP web services implementation
XML/HTTP web services are implemented in the Nun.Me.Shu framework as follows:
(1) standard web service URL templates are defined in an ENT entity file.
(2) special web service XML element tags are defined in the web page DTD.
(3) a web page is created using the special web service XML tags.
(4) the XSL stylesheet contains web-service-specific templates to:
   (a) read the web page XML content,
   (b) parse the template URLs and fill in the right parameter values,
   (c) request the XML data from the web service using the document() function,
   (d) parse and transform the received XML into HTML.
These components are detailed below, using the implementation of Amazon.com's web service as an example.

Shortcuts to web service components
°   (1) URL templates
°   (2) XML content tags
°   (3) web page
°   (4) XSL templates


(1) URL templates
The Nun.Me.Shu framework has a defs_env.ent entity file, which contains all URL references the stylesheet uses. In this file is a section for the amazon-related URLs:
<!ENTITY amazon_ass_id "-!-INSERT_YOUR_OWN_ASSOCIATION_ID_HERE-!-">
<!ENTITY amazon_dev_token "-!-INSERT_YOUR_OWN_DEVELOPERS_TOKEN_HERE-!-">
<!ENTITY amazon_ass_home_uri "http://www.amazon.com/exec/obidos/redirect-
home/&amazon_ass_id;">
<!ENTITY amazon_ass_asin_uri_tmpl "http://www.amazon.com/exec/obidos/ASIN/
[asin]/ref=ase_&amazon_ass_id;">
<!ENTITY amazon_xml_productlist_uri_tmpl "http://xml.amazon.com/onca/xml?
v=1.0&t=&amazon_ass_id;&dev-t=&amazon_dev_token;&BrowseNodeSearch=[browseid]
&mode=[mode]&type=[type]&page=[page]&f=xml">
<!ENTITY amazon_xml_asin_uri_tmpl "http://xml.amazon.com/onca/xml?v=1.0
&t=&amazon_ass_id;&dev-t=&amazon_dev_token;&AsinSearch=[asin]&type=[type]&f=xml">
<!ENTITY amazon_xml_keywordsearchlist_uri_tmpl "http://xml.amazon.com/onca/xml?
v=1.0&t=&amazon_ass_id;&dev-t=&amazon_dev_token;&KeywordSearch=[keywords]
&mode=[mode]&type=[type]&page=[page]&f=xml">
The first two entities are an association id and a developers token that are required in order to access Amazon's web service. Since they have to be entered in different URLs they are defined separately.
The third entity is an "old-fashioned" link to an Amazon product page.
The last three entities (with names ending in "_tmpl") are templates for the URLs that request information from Amazon's web service. Note that they have some querystring values in square brackets (for instance "type=[type]"). These are the values that tell the web service what kind of data is requested. These sections of the URL have to be parsed by the stylesheet and replaced by values provided by the content XML of a web page.




(2) XML content tags
Three different ways of requesting information from the web service are implemented, each with their own special XML tag. These tags can be used by content editors to put in the XML content file of a web page.

(2a) Information about individual products can be requested with:
<amazonproduct asin="xxxxxxxxxx" type="lite"/>
This element has just one relevant attribute asin which should have the value of an Amazon product ID (ASIN); in the case of a book, this is equivalent to the book's ISBN.

(2b) A list of products based on a keyword search can be requested with:
<amazonkeywordslist keywords="xxxxxxxx" mode="xxxxxxx" page="1" type="lite" ignore="xxxxxx"/>
This element has two relevant attributes: keywords, containing the keywords to search products for (for instance "XML+XSL"), and mode, containing the type of products to search for (for instance "books").

(2c) A list of products based on an Amazon catalog id can be requested with:
<amazoncataloglist browseid="xx" mode="xxxxxxx" page="1" type="lite" ignore="xxxxxx"/>
This element has two relevant attributes: browseid, containing an Amazon catalog id (for instance "5" which corresponds with "Books, Computers/Internet"), and mode, containing the type of products to search for (for instance "books").

The type attribute in all three requests is used to indicate how much information is needed: type="lite" returns basic product information like the product's name and price, while type="heavy" returns additional information like sales ranking and customer reviews. The page attribute in the two product list requests is used to select a sub set of the search results: page="1" returns the first 10 results, page="2" returns the next 10 results, etc. The ignore attribute can be used to filter out any unwanted results from the returned lists: products with names that contain the string specified in ignore will be ignored.

Note the simple way in which a content editor can access a web service. All details and complexity of web service invocations are hidden behind a few simple XML elements, which only have some basic attributes that relate directly to the content request.




(3) web page
As an example, the XML source of my store web page has the following elements to display the Amazon product information:
Note that I have left in place the XML elements that wrap the three store sections in an indexed list; the amount of information to describe the indexed list is greater than the amount of information to request Amazon's product information...
<indexedlist>
   <indexheader>Shortcuts to the different store sections</indexheader>
   <indexedlistitem>
      <indexitem>My personal recommendations (1)</indexitem>
      <listitem>
         <para>
            <amazonproducts>
               <amazonproduct asin="1861003129" type="lite">
                  <review>
                     <i>XSLT - Programmer's Reference</i> by Michael Kay is the XSL 'bible' in my opinion. If you have a budget to just buy one book about XSL, this would be the book to buy. (In fact, this is the only book I have about XSL, and I never felt a need for an additional reference).
                  </review>
               </amazonproduct>

               <amazonproduct asin="1861005067" type="lite">
                  <review>
                     <i>XSLT - Programmer's Reference 2nd edition</i> by Michael Kay is the successor of above mentioned book.
                  </review>
               </amazonproduct>

               <amazonproduct asin="1565924940" type="lite">
                  <review>
                     <i>Dynamic HTML: The Definitive Reference</i> does not realy live up to its title, but it's the only book about DHTML, CSS and JavaScript that I have and it answers most questions, as long as you know what to look for. It is a good reference to find the specifics of a certain HTML tag or CSS attribute. But if you'd like to know what the best approach to a certain problem is you are left in the cold.
                  </review>
               </amazonproduct>
            </amazonproducts>
         </para>
      </listitem>
   </indexedlistitem>

   <indexedlistitem>
      <indexitem>Amazon recommends for the keywords 'xml xsl' (2)</indexitem>
      <listitem>
         <para>
            <!-- replace spaces in keyword list with "+" sign -->
            <amazonkeywordslist keywords="xml+xsl" mode="books" page="1" type="lite"/>
         </para>
      </listitem>
   </indexedlistitem>

   <indexedlistitem>
      <indexitem>Amazon recommends for the category 'Books, Computers/Internet' (3)</indexitem>
      <listitem>
         <para>
            <!-- browseid="5" equals "Books, Computers/Internet" -->
            <amazoncataloglist browseid="5" mode="books" page="1" type="lite"/>
         </para>
      </listitem>
   </indexedlistitem>
</indexedlist>
Note that above fragment has three <amazonproduct> elements which are wrapped in an <amazonproducts> (plural) element. Also note that an <amazonproduct> element may have a <review> child element, which allows a site editor to add his own review of a product.




(4) XSL templates
Each of the three XML elements described in (2) above has its own XSL template. The three templates are very similar though, so I'll limit myself here to the template for <amazonkeywordslist>.
Calls to a debug template have been left out, since they are not essential to the understanding of the basic functionality.
<xsl:template match="amazonkeywordslist">
   <!-- construct the amazon web service URL -->
   <xsl:variable name="searchattributes" select="@*"/>
   <xsl:variable name="amazon_xml_keywordsearchlist_uri">
      <xsl:call-template name="_fill_in_the_blanks">
         <xsl:with-param name="tmpl_string">
            &amazon_xml_keywordsearchlist_uri_tmpl;
         </xsl:with-param>
         <xsl:with-param name="attributes" select="$searchattributes"/>
      </xsl:call-template>
   </xsl:variable>

   <!-- call amazon's XML/HTTP web service to request for product information -->
   <xsl:variable name="productinfo"
   select="document($amazon_xml_keywordsearchlist_uri)/ProductInfo"/>

   <!-- transform the data send back by amazon -->
   <xsl:call-template name="_show_productinfo">
      <xsl:with-param name="productinfo" select="$productinfo"/>
      <xsl:with-param name="ignore" select="@ignore"/>
   </xsl:call-template>
</xsl:template>
This template has three sections:
The first section constructs the amazon web service URL. It places all attributes of the <amazonkeywordslist> from the content XML file -see (2) and the example in (3)- in a variable named searchattributes. This variable now contains all information needed for the amazon web service request. A call to a special (rather sophisticated) template _fill_in_the_blanks takes the template url &amazon_xml_keywordsearchlist_uri_tmpl; that was defined in the env_defs.ent file -see (1)- and replaces the querystring placeholders with the actual values that can be found in the searchattributes variable.
The second section takes the just constructed URL, fetches the XML product data from amazon using the document() function, and places the returned node-set in a variable productinfo.
The third section calls a template _show_productinfo to transform the returned product data.

The _show_productinfo template looks like:
<!-- named template for the display of product information -->
<xsl:template name="_show_productinfo">
   <xsl:param name="productinfo"/>
   <xsl:param name="ignore"/>
   <div class="subSection">
      <table border="0" width="100%" cellpadding="0" cellspacing="{$cellspacing}">
         <!-- transform the product information -->
         <xsl:apply-templates select="$productinfo" mode="withdivider">
            <xsl:with-param name="ignore" select="$ignore"/>
         </xsl:apply-templates>
         <!-- show an error message in case no product information was returned -->
         <xsl:if test="not($productinfo)">
            <tr>
               <td colspan="3">
                  <div class="error">
                     &amazon_error_msg;
                  </div>
               </td>
            </tr>
         </xsl:if>
      </table>
   </div>
</xsl:template>
The main function of this template is to serve as a gateway to the actual templates that transform the amazon product XML node set (which was placed in variable productinfo), and to allow for error-detection in case the HTTP-call to amazon did not return any results.
Note that the error message is an entity &amazon_error_msg;: an example of the strict separation between content and presentation in the Nun.Me.Shu framework. The content of the error message is specified in a separate entity file defs_content.ent which contains all site-wide content fragments that the stylesheet uses.

The rest of the amazon XSL templates deal with the transformation, layout and display of the amazon product data, which is of little interest here. [view complete Amazon stylesheet]New page displays in separate browser window