O'Reilly logo

Java Web Services: Up and Running by Martin Kalin

Stay ahead with the world's most comprehensive technology and business learning platform.

With Safari, you learn the way you learn best. Get unlimited access to videos, live online training, learning paths, books, tutorials, and more.

Start Free Trial

No credit card required

WADLing with Java-Based RESTful Services

In SOAP-based web services, the WSDL document is a blessing to programmers because this service contract can be used to generate client-side artifacts and, indeed, even a service-side interface. RESTful services do not have an official or even widely accepted counterpart to the WSDL, although there are efforts in that direction. Among them is the WADL initiative. WADL stands for Web Application Description Language.

The WADL download includes the wadl2java utility, a library of required JAR files, and a sample WADL file named YahooSearch.wadl. The download also has Ant, Maven, and command-line scripts for convenience. To begin, here is a Yahoo! client that uses wadl2java-generated artifacts:

import com.yahoo.search.ResultSet;
import com.yahoo.search.ObjectFactory;
import com.yahoo.search.Endpoint;
import com.yahoo.search.Endpoint.NewsSearch;
import com.yahoo.search.Type;
import com.yahoo.search.Result;
import com.yahoo.search.Sort;
import com.yahoo.search.ImageType;
import com.yahoo.search.Output;
import com.yahoo.search.Error;
import com.yahoo.search.SearchErrorException;
import javax.xml.bind.JAXBException;
import java.io.IOException;
import java.util.List;

class YahooWADL {
    public static void main(String[ ] args) {
        if (args.length < 1) {
            System.err.println("Usage: YahooWADL <app id>");
            return;
        }
        String app_id = args[0];
        try {
            NewsSearch service = new NewsSearch();
            String query = "neutrino";

            ResultSet result_set = service.getAsResultSet(app_id, query);
            List<Result> list = result_set.getResultList();
            int i = 1;
            for (Result next : list) {
                String title = next.getTitle();
                String click = next.getClickUrl();
                System.out.printf("(%d) %s %s\n", i++, title, click);
            }
        }
        catch(JAXBException e) { System.err.println(e); }
        catch(SearchErrorException e) { System.err.println(e); }
        catch(IOException e) { System.err.println(e); }
    }
}    

The code is cleaner than my original YahooClient. The wadl2java-generated code hides the XML processing and other grimy details such as the formatting of an appropriate query string for a GET request against the Yahoo! News Service. The client-side artifacts also include utility classes for getting images from the Yahoo! service. On a sample run, the YahooWADL client produced this output on a request for articles that include the keyword neutrino:

(1) Congress to the rescue for Fermi jobs http://www.dailyherald.com/story/...
(2) AIP FYI #69: Senate FY 2009 National Science Foundation Funding Bill...
(3) Linked by Thom Holwerda on Wed 12th Sep 2007 11:51 UTC...
(4) The World's Nine Largest Science Projects http://science.slashdot.org/...
(5) Funding bill may block Fermi layoffs http://www.suntimes.com/business/...
(6) In print http://www.sciencenews.org/view/generic/id/33654/title/For_Kids...
(7) Recent Original Stories http://www.osnews.com/thread?284017
(8) Antares : un télescope pointé vers le sol qui utilise la terre comme filtre...
(9) Software addresses quality of hands-free car phone audio...
(10) Planetary science: Tunguska at 100 http://www.nature.com/news/2008/...

Here is the WADL document used to generate the client-side artifacts:

<?xml version="1.0"?>
<!--
The contents of this file are subject to the terms of the Common Development and 
Distribution License (the "License").  You may not use this file except in  
compliance with the License. You can obtain a copy of the license at 
     http://www.opensource.org/licenses/cddl1.php
See the License for the specific language governing
permissions and limitations under the License.
-->
<application xmlns:xsd="http://www.w3.org/2001/XMLSchema"
             xmlns:yn="urn:yahoo:yn"
             xmlns:ya="urn:yahoo:api"
             xmlns:html="http://www.w3.org/1999/xhtml"
             xmlns="http://research.sun.com/wadl/2006/10">
  <grammars>
    <include href="NewsSearchResponse.xsd"/>
    <include href="NewsSearchError.xsd"/>
  </grammars>

  <resources base="http://api.search.yahoo.com/NewsSearchService/V1/">
    <resource path="newsSearch">
      <doc xml:lang="en" title="Yahoo News Search Service">
        The <html:i>Yahoo News Search</html:i> service provides online 
                    searching of news stories from around the world.
      </doc>
      <param name="appid" type="xsd:string" required="true" style="query">
        <doc>The application ID. See 
         <html:a href="http://developer.yahoo.com/faq/index.html#appid">
           Application IDs
         </html:a> for more information.
        </doc>
      </param>
      <method href="#search"/>
    </resource>
  </resources>

  <method name="GET" id="search">
    <doc xml:lang="en" title="Search news stories by keyword"/>
    <request>
      <param name="query" type="xsd:string" required="true" style="query">
        <doc xml:lang="en" title="Space separated keywords to search for"/>
      </param>
      <param name="type" type="xsd:string" default="all" style="query">
        <doc xml:lang="en" title="Keyword matching"/>
        <option value="all">
          <doc>All query terms.</doc>
        </option>
        <option value="any">
          <doc>Any query terms.</doc>
        </option>
        <option value="phrase">
          <doc>Query terms as a phrase.</doc>
        </option>
      </param>
      <param name="results" type="xsd:int" default="10" style="query">
        <doc xml:lang="en" title="Number of results"/>
      </param>
      <param name="start" type="xsd:int" default="1" style="query">
        <doc xml:lang="en" title="Index of first result"/>
      </param>
      <param name="sort" type="xsd:string" default="rank" style="query">
        <doc xml:lang="en" title="Sort by date or rank"/>
        <option value="rank"/>
        <option value="date"/>
      </param>
      <param name="language" type="xsd:string" style="query">
        <doc xml:lang="en" title="Language filter, omit for any language"/>
      </param>
      <param name="output" type="xsd:string" default="xml" style="query">
        <doc>The format for the output. If <html:em>json</html:em> is requested, 
             the results will be returned in 
             <html:a href="http://developer.yahoo.com/common/json.html">
                  JSON
             </html:a> format. If <html:em>php</html:em> is requested, the 
             results will be returned in 
              <html:a href="http://developer.yahoo.com/common/phpserial.html">
                 Serialized PHP
              </html:a> format.
        </doc>
        <option value="xml"/>
        <option value="json"/>
        <option value="php"/>
      </param>
      <param name="callback" type="xsd:string" style="query">
        <doc>The name of the callback function to wrap around the JSON data. 
             The following characters are allowed: A-Z a-z 0-9 . 
             [ ] and _. If output=json has not been requested, this 
             parameter has no effect. More information on the callback can be 
             found in the 
             <html:a href="http://developer.yahoo.com/common/json.html
             #callbackparam">Yahoo! Developer Network JSON 
             Documentation</html:a>.
      </doc>
      </param>
    </request>
    <response>
      <representation mediaType="application/xml" element="yn:ResultSet">
        <doc xml:lang="en" title="A list of news items matching the query"/>
      </representation>
      <fault id="SearchError" status="400" mediaType="application/xml"
             element="ya:Error"/>
    </response>
  </method>
</application>  

The WADL document begins with references to two XSD documents, one of which is the grammar for error documents and the other of which is the grammar for normal response documents from the service. Next comes a list of available resources, in this case only the news search service. The methods section describes the HTTP verbs and, by implication, the CRUD operations that can be used against the service. In the case of the Yahoo! news service, only GET requests are allowed. The remaining sections provide details about the parameters that can accompany requests and responses. XSD type information of the sort found in WSDL documents occurs throughout the WADL as well.

Executing the wadl2java utility on the YahooSearch.wadl file generates 11 Java source files, the most important of which for the client-side programmer is Endpoint.java. The Endpoint class encapsulates the static class NewsSearch, an instance of which has utility methods such as getAsResultSet. For reference, here is the main segment of the client YahooWADL shown earlier. The WADL artifacts allow the code to be short and clear:

NewsSearch service = new NewsSearch();
String query = "neutrino";

ResultSet result_set = service.getAsResultSet(app_id, query);
List<Result> list = result_set.getResultList();
int i = 1;
for (Result next : list) {
   String title = next.getTitle();
   String click = next.getClickUrl();
   System.out.printf("(%d) %s %s\n", i++, title, click);
}    

The search string, given in this case with the object reference query, is just a list of keywords separated by blanks. The NewsSearch object has properties for specifying sort order, the maximum number of items to return, and the like. The generated artifacts do lighten the coding burden.

WADL has stirred interest and discussion but remains, for now, a Java-centric initiative. The critical issue is whether REST-style services can be standardized to the extent that utilities such as wadl2java and perhaps java2wadl can measure up to the utilities now available for SOAP-based services. If it is fair to criticize SOAP-based services for being over-engineered, it is also fair to fault REST-style services for being under-engineered.

Problems in the wadl2java-Generated Code

Among the files that the wadl2java utility generates are Error.java and ObjectFactory.java. In each file, any occurrences of urn:yahoo:api should be changed to urn:yahoo:yn. In the 1.0 distribution, there were two occurrences in each source file. Without these changes, a JAX-B exception is thrown when the results from the Yahoo! search are unmarshaled into Java objects. The changes could be made to the XSD document and the WADL document that the wadl2java utility uses.

With Safari, you learn the way you learn best. Get unlimited access to videos, live online training, learning paths, books, interactive tutorials, and more.

Start Free Trial

No credit card required