Gentle introduction to WADL (in Java)
Join the DZone community and get the full member experience.
Join For FreeIn principle WADL is similar to WSDL, but the structure of the language is much different. Whilst WSDL defines a flat list of messages and operations either consuming or producing some of them, WADL emphasizes the hierarchical nature of RESTful web services. In REST, the primary artifact is the resource. Each resource (noun) is represented as an URI. Every resource can define both CRUD operations (verbs, implemented as HTTP methods) and nested resources. The nested resource has a strong relationship with a parent resource, typically representing an ownership.
A simple example would be http://example.com/api/books resource representing a list of books. You can (HTTP) GET this resource, meaning to retrieve the whole list. You can also GET the http://example.com/api/books/7 resource, fetching the details of 7th book inside books resource. Or you can even PUT new version or DELETE the resource altogether using the same URI. You are not limited to a single level of nesting: GETting http://example.com/api/books/7/reviews?page=2&size=10 will retrieve the second page (up to 10 items) of reviews of 7th book. Obviously you can also place other resources next to books, like http://example.com/api/readers
The requirement arose to formally and precisely describe every available resource, method, request and response, just like WSDL guys were able to do. WADL is one of the options to describe “available URIs", although some believe that well-written REST service should be self-descriptive (see HATEOAS). Nevertheless here is a simple, empty WADL document:
<application xmlns="http://wadl.dev.java.net/2009/02"> <resources base="http://example.com/api"/> </application>
Nothing fancy here. Note that the <resources> tag defines base API address. All named resources, which we are just about to add, are relative to this address. Also you can define several <resources> tags to describe more than one APIs. So, let's add a simple resource:
<application xmlns="http://wadl.dev.java.net/2009/02"> <resources base="http://example.com/api"> <resource path="books"> <method name="GET"/> <method name="POST"/> </resource> </resources> </application>
This defines resource under http://example.com/api/books
with two methods possible: GET to retrieve the whole list and POST to
create (add) new item. Depending on your requirements you might want to
allow DELETE method as well (to delete all items), and it is the responsibility of WADL to document what is allowed.
Remember our example at the beginning: /books/7? Obviously 7
is just an example and we won't declare every possible book id in WADL.
Instead there is a handy placeholder syntax:There are two important aspects you should note: first, The
<application xmlns="http://wadl.dev.java.net/2009/02"> <resources base="http://example.com/api"> <resource path="books"> <method name="GET"/> <resource path="{bookId}"> <param required="true" style="template" name="bookId"/> <method name="GET"/> </resource> </resource> </resources> </application>
{bookId} place-holder was used in place of nested resource. Secondly, to make it clear, we are documenting this place-holder using <param/> tag. We will see soon how it can be used in combination with methods. Just to make sure you are still with me, the document above describes GET /books and GET /books/some_id resources.
We will stop here and only mention about remaining pieces of WADL. First of all, as you have probably guessed so far, there is also a <response/> child tag possible for each <method/>. Both request and response can define exact grammar (e.g. in XML Schema) that either the request or the response must follow. The response can also document possible HTTP response codes. But since we will be using the knowledge you have gained so far in a code-first application, I intentionally left the <grammars/> definition. WADL is agile and it allows you to define as little (or as much) information as you need.
So we know the basics of WADL, now we would like to use it, maybe as a consumer or as a producer in a Java-based application. Fortunately there is a wadl.xsd XML Schema description of the language itself, which we can use to generate JAXB-annotated POJOs to work with (using xjc tool in the JDK):
$ wget http://www.w3.org/Submission/wadl/wadl.xsd $ xjc wadl.xsdAnd there it... hangs! The life of a software developer is full of challenges and non-trivial problems. And sometimes it is just an annoying network filter that makes suspicious packets (together with half hour of your life) disappear. It is not hard to spot the problem, once you recall that article written around 2008: W3C’s Excessive DTD Traffic:
<xs:import namespace="http://www.w3.org/XML/1998/namespace"
schemaLocation="http://www.w3.org/2001/xml.xsd"/>
$ xjc wadl.xsd parsing a schema... compiling a schema... net/java/dev/wadl/_2009/_02/Application.java net/java/dev/wadl/_2009/_02/Doc.java net/java/dev/wadl/_2009/_02/Grammars.java net/java/dev/wadl/_2009/_02/HTTPMethods.java net/java/dev/wadl/_2009/_02/Include.java net/java/dev/wadl/_2009/_02/Link.java net/java/dev/wadl/_2009/_02/Method.java net/java/dev/wadl/_2009/_02/ObjectFactory.java net/java/dev/wadl/_2009/_02/Option.java net/java/dev/wadl/_2009/_02/Param.java net/java/dev/wadl/_2009/_02/ParamStyle.java net/java/dev/wadl/_2009/_02/Representation.java net/java/dev/wadl/_2009/_02/Request.java net/java/dev/wadl/_2009/_02/Resource.java net/java/dev/wadl/_2009/_02/ResourceType.java net/java/dev/wadl/_2009/_02/Resources.java net/java/dev/wadl/_2009/_02/Response.java net/java/dev/wadl/_2009/_02/package-info.javaSince we'll be using these classes in a maven based project (and I hate committing generated classes to source repository), let's move xjc execution to maven lifecycle:
From http://nurkiewicz.blogspot.com/2012/01/gentle-introduction-to-wadl-in-java.html
Opinions expressed by DZone contributors are their own.
Comments