You are previewing RESTful Web Services.

RESTful Web Services

Cover of RESTful Web Services by Leonard Richardson... Published by O'Reilly Media, Inc.
  1. RESTful Web Services
    1. SPECIAL OFFER: Upgrade this ebook with O’Reilly
    2. A Note Regarding Supplemental Files
    3. Foreword
    4. Preface
      1. The Web Is Simple
      2. Big Web Services Are Not Simple
      3. The Story of the REST
      4. Reuniting the Webs
      5. What’s in This Book?
      6. Administrative Notes
      7. Conventions Used in This Book
      8. Using Code Examples
      9. Safari® Enabled
      10. How to Contact Us
      11. Acknowledgments
    5. 1. The Programmable Web and Its Inhabitants
      1. Kinds of Things on the Programmable Web
      2. HTTP: Documents in Envelopes
      3. Method Information
      4. Scoping Information
      5. The Competing Architectures
      6. Technologies on the Programmable Web
      7. Leftover Terminology
    6. 2. Writing Web Service Clients
      1. Web Services Are Web Sites
      2. del.icio.us: The Sample Application
      3. Making the Request: HTTP Libraries
      4. Processing the Response: XML Parsers
      5. JSON Parsers: Handling Serialized Data
      6. Clients Made Easy with WADL
    7. 3. What Makes RESTful Services Different?
      1. Introducing the Simple Storage Service
      2. Object-Oriented Design of S3
      3. Resources
      4. HTTP Response Codes
      5. An S3 Client
      6. Request Signing and Access Control
      7. Using the S3 Client Library
      8. Clients Made Transparent with ActiveResource
      9. Parting Words
    8. 4. The Resource-Oriented Architecture
      1. Resource-Oriented What Now?
      2. What’s a Resource?
      3. URIs
      4. Addressability
      5. Statelessness
      6. Representations
      7. Links and Connectedness
      8. The Uniform Interface
      9. That’s It!
    9. 5. Designing Read-Only Resource-Oriented Services
      1. Resource Design
      2. Turning Requirements Into Read-Only Resources
      3. Figure Out the Data Set
      4. Split the Data Set into Resources
      5. Name the Resources
      6. Design Your Representations
      7. Link the Resources to Each Other
      8. The HTTP Response
      9. Conclusion
    10. 6. Designing Read/Write Resource-Oriented Services
      1. User Accounts as Resources
      2. Custom Places
      3. A Look Back at the Map Service
    11. 7. A Service Implementation
      1. A Social Bookmarking Web Service
      2. Figuring Out the Data Set
      3. Resource Design
      4. Design the Representation(s) Accepted from the Client
      5. Design the Representation(s) Served to the Client
      6. Connect Resources to Each Other
      7. What’s Supposed to Happen?
      8. What Might Go Wrong?
      9. Controller Code
      10. Model Code
      11. What Does the Client Need to Know?
    12. 8. REST and ROA Best Practices
      1. Resource-Oriented Basics
      2. The Generic ROA Procedure
      3. Addressability
      4. State and Statelessness
      5. Connectedness
      6. The Uniform Interface
      7. This Stuff Matters
      8. Resource Design
      9. URI Design
      10. Outgoing Representations
      11. Incoming Representations
      12. Service Versioning
      13. Permanent URIs Versus Readable URIs
      14. Standard Features of HTTP
      15. Faking PUT and DELETE
      16. The Trouble with Cookies
      17. Why Should a User Trust the HTTP Client?
    13. 9. The Building Blocks of Services
      1. Representation Formats
      2. Prepackaged Control Flows
      3. Hypermedia Technologies
    14. 10. The Resource-Oriented Architecture Versus Big Web Services
      1. What Problems Are Big Web Services Trying to Solve?
      2. SOAP
      3. WSDL
      4. UDDI
      5. Security
      6. Reliable Messaging
      7. Transactions
      8. BPEL, ESB, and SOA
      9. Conclusion
    15. 11. Ajax Applications as REST Clients
      1. From AJAX to Ajax
      2. The Ajax Architecture
      3. A del.icio.us Example
      4. The Advantages of Ajax
      5. The Disadvantages of Ajax
      6. REST Goes Better
      7. Making the Request
      8. Handling the Response
      9. JSON
      10. Don’t Bogart the Benefits of REST
      11. Cross-Browser Issues and Ajax Libraries
      12. Subverting the Browser Security Model
    16. 12. Frameworks for RESTful Services
      1. Ruby on Rails
      2. Restlet
      3. Django
    17. A. Some Resources for REST and Some RESTful Resources
      1. Standards and Guides
      2. Services You Can Use
    18. B. The HTTP Response Code Top 42
      1. Three to Seven Status Codes: The Bare Minimum
      2. 1xx: Meta
      3. 2xx: Success
      4. 3xx: Redirection
      5. 4xx: Client-Side Error
      6. 5xx: Server-Side Error
    19. C. The HTTP Header Top Infinity
      1. Standard Headers
      2. Nonstandard Headers
    20. Index
    21. About the Authors
    22. Colophon
    23. SPECIAL OFFER: Upgrade this ebook with O’Reilly
O'Reilly logo

Hypermedia Technologies

There are two kinds of hypermedia: links and forms. A link is a connection between the current resource and some target resource, identified by its URI. Less formally, a link is any URI found in the body of a representation. Even JSON and plain text are hypermedia formats of a sort, since they can contain URIs in their text. But throughout this book when I say “hypermedia format,” I mean a format with some kind of structured support for links and forms.

There are two kinds of forms. The simplest kind I’ll call application forms, because they show the client how to manipulate application state. An application form is a way of handling resources whose names follow a pattern: it basically acts as a link with more than one destination. A search engine doesn’t link to every search you might possibly make: it gives you a form with a space for you to type in your search query. When you submit the form, your browser constructs a URI from what you typed into the form (say, http://www.google.com/search?q=jellyfish), and makes a GET request to that URI. The application form lets one resource link to an infinite number of others, without requiring an infinitely large representation.

The second kind of form I’ll call resource forms, because they show the client how to format a representation that modifies the state of a resource. GET and DELETE requests don’t need representations, of course, but POST and PUT requests often do. Resource forms say what the client’s POST and PUT representations should look like.

Links and application forms implement what I call connectedness, and what the Fielding thesis calls “hypermedia as the engine of application state.” The client is in charge of the application state, but the server can send links and forms that suggest possible next states. By contrast, a resource form is a guide to changing the resource state, which is ultimately kept on the server.

I cover four hypermedia technologies in this section. As of the time of writing, XHTML 4 is the only hypermedia technology in active use. But this is a time of rapid change, thanks in part to growing awareness of RESTful web services. XHTML 5 is certain to be widely used once it’s finally released. My guess is that URI Templates will also catch on, whether or not they’re incorporated into XHTML 5. WADL may catch on, or it may be supplanted by a combination of XHTML 5 and microformats.

URI Templates

URI Templates (currently an Internet Draft) are a technology that makes simple resource forms look like links. I’ve used URI Template syntax whenever I want to show you an infinite variety of similar URIs. There was this example from Chapter 3, when I was showing you the resources exposed by Amazon’s S3 service:

https://s3.amazonaws.com/{name-of-bucket}/{name-of-object}

That string is not a valid URI, because curly brackets aren’t valid in URIs, but it is a valid URI Template. The substring {name-of-bucket} is a blank to be filled in, a placeholder to be replaced with the value of the variable name-of-bucket. There are an infinite number of URIs lurking in that one template, including https://s3.amazonaws.com/bucket1/object1, https://s3.amazonaws.com/my-other-bucket/subdir/SomeObject.avi, and so on.

URI templating gives us a precise way to play fill-in-the-blanks with URIs. Without URI Templates, a client must rely on preprogrammed URI construction rules based on English descriptions like “https://s3.amazonaws.com/, and then the bucket name.”

URI Templates are not a data format, but any data format can improve its hypermedia capabilities by allowing them. There is currently a proposal to support URI Templates in XHTML 5, and WADL supports them already.

XHTML 4

HTML is the most successful hypermedia format of all time, but its success on the human web has typecast it as sloppy, and sent practitioners running for the more structured XML. The compromise standard is XHTML, an XML vocabulary for describing documents which uses the same tags and attributes found in HTML. Since it’s basically the same as HTML, XHTML has a powerful set of hypermedia features, though its forms are somewhat anemic.

XHTML 4 links

A number of HTML tags can be used to make hypertext links (consider img, for example), but the two main ones are link and a. A link tag shows up in the document’s head, and connects the document to some resource. The link tag contains no text or other tags: it applies to the entire document. An a tag shows up in the document’s body. It can contain text and other tags, and it links its contents (not the document as a whole) to another resource (see Example 9-8).

Example 9-8. An XHTML 4 document with some links

<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
 <head>
  <link rel="alternate" type="application/atom+xml" href="atom.xml">
  <link rel="stylesheet" href="display.css">
 </head>

 <body>
  <p>
   Have you read 
   <a href="Great-Expectations.html"><i>Great Expectations</i></a>?
  </p>
 </body>
</html>

Example 9-8 shows a simple HTML document that contains both sorts of hyperlinks. There are two links that use link to relate the document as a whole to other URIs, and there’s one link that uses a to relate part of the document (the italicized phrase “Great Expectations”) to another URI.

The three important attributes of link and a tags are href, rel, and rev. The href attribute is the most important: it gives the URI of the resource that’s being linked to. If you don’t have an href attribute, you don’t have a hyperlink.

The rel attribute adds semantics that explain the foreign URI’s relationship to this document. I mentioned this attribute earlier when I was talking about microformats. In Example 9-8, the relationship of the URI atom.xml to this document is “alternate”. The relationship of the URI display.css to this document is “stylesheet”. These particular values for rel are among the 15 defined in the HTML 4 standard. The value “alternate” means that the linked URI is an alternate representation of the resource this document represents. The value “stylesheet” means that the linked URI contains instructions on how to format this document for display. Microformats often define additional values for rel. The rel-nofollow microformat defines the relationship “nofollow”, to show that a document doesn’t trust the resource it’s linking to.

The rev attribute is the exact opposite of rel: it explains the relationship of this document to the foreign URI. The VoteLinks microformat lets you express your opinion of a URI by setting rev to “vote-for” or “vote-against”. In this case, the foreign URI probably has no relationship to you, but you have a relationship to it.

A simple example illustrates the difference between rel and rev. Here’s an HTML snippet of a user’s home page, which contains two links to his father’s home page.

<a rel="parent" href="/Dad">My father</a>
<a rev="child" href="/Dad">My father</a>

XHTML 4 forms

These are the forms that drive the human web. You might not have known about the rel and rev attributes, but if you’ve done any web programming, you should be familiar with the hypermedia capabilities of XHTML forms.

To recap what you might already know: HTML forms are described with the form tag. A form tag has a method attribute, which names the HTTP method the client should use when submitting the form. It has an action attribute, which gives the (base) URI of the resource the form is accessing. It also has an enctype attribute, which gives the media type of any representation the client is supposed to send along with the request.

A form tag can contain form elements: children like input and select tags. These show up in web browsers as GUI elements: text inputs, checkboxes, buttons, and the like. In application forms, the values entered into the form elements are used to construct the ultimate destination of a GET request. Here’s an application form I just made up: an interface to a search engine.

<form method="GET" action="http://search.example.com/search">
 <input name="q" type="text">
 <input type="submit" />
</form>

Since this is an application form, it’s not designed to operate on any particular resource. The point of the form is to use the URI in the action as a jumping-off point to an infinity of resources with user-generated URIs: http://search.example.com/search?q=jellyfish, http://search.example.com/search?q=chocolate, and so on.

A resource form in HTML 4 identifies one particular resource, and it specifies an action of POST. The form elements are used to build up a representation to be sent along with the POST request. Here’s a resource form I just made up: an interface to a file upload script.

<form method="POST" action="http://files.example.com/dir/subdir/" 
enctype="multipart/form-data">
 <input type="text" name="description" />
 <input type="file" name="newfile" />
</form>

This form is designed to manipulate resource state, to create a new “file” resource as a subordinate resource of the “directory” resource at http://files.example.com/dir/subdir/. The representation format is a “multipart/form-data” document that contains a textual description and a (possibly binary) file.

Shortcomings of XHTML 4

HTML 4’s hypermedia features are obviously good enough to give us the human web we enjoy today, but they’re not good enough for web services. I have five major problems with HTML’s forms.

  1. Application forms are limited in the URIs they can express. You’re limited to URIs that take a base URI and then tack on some key-value pairs. With an HTML application form you can “link” to http://search.example.com/search?q=jellyfish, but not http://search.example.com/search/jellyfish. The variables must go into the URI’s query string as key-value pairs.

  2. Resource forms in HTML 4 are limited to using HTTP POST. There’s no way to use a form to tell a client to send a DELETE request, or to show a client what the representation of a PUT request should look like. The human web, which runs on HTML forms, has a different uniform interface from web services as a whole. It uses GET for safe operations, and overloaded POST for everything else. If you want to get HTTP’s uniform interface with HTML 4 forms, you’ll need to simulate PUT and DELETE with overloaded POST (see Faking PUT and DELETE” in Chapter 8 for the standard way).

  3. There’s no way to use an HTML form to describe the HTTP headers a client should send along with its request. You can’t define a form entity and say “the value of this entity goes into the HTTP request header X-My-Header.” I generally don’t think services should require this of their clients, but sometimes it’s necessary. The Atom Publishing Protocol defines a special request header (Slug, mentioned above) for POST requests that create a new member in a collection. The APP designers defined a new header, instead of requiring that this data go into the entity-body, because the entity-body might be a binary file.

  4. You can’t use an HTML form to specify a representation more complicated than a set of key-value pairs. All the form elements are designed to be turned into key-value pairs, except for the “file” element, which doesn’t help much. The HTML standard defines two content types for form representations: application/x-www-form-urlencoded, which is for key-value pairs (I covered it in Form-encoding” in Chapter 6); and multipart/form-data, which is for a combination of key-value pairs and uploaded files.

    You can specify any content type you want in enctype, just as you can put anything you want in a tag’s class and rel attributes. So you can tell the client it should POST an XML file by setting a form’s enctype to application/xml. But there’s no way of conveying what should go into that XML file, unless it happens to be an XML representation of a bunch of key-value pairs. You can’t nest form elements, or define new ones that represent data structures more complex than key-value pairs. (You can do a little better if the XML vocabulary you’re using has its own media type, like application/atom+xml or application/rdf+xml.)

  5. As I mentioned in Link the Resources to Each Other” in Chapter 5, you can’t define a repeating field in an HTML form. You can define the same field twice, or ten times, but eventually you’ll have to stop. There’s no way to tell the client: “you can specify as many values as you want for this key-value pair.”

XHTML 5

HTML 5 solves many of the problems that turn up when you try to use HTML on the programmable web. The main problem with HTML 5 is the timetable. The official estimate has HTML 5 being adopted as a W3C Proposed Recommendation in late 2008. More conservative estimates push that date all the way to 2022. Either way, HTML 5 won’t be a standard by the time this book is published. That’s not really the issue, though. The issue is when real clients will start supporting the HTML 5 features I describe below. Until they do, if you use the features of HTML 5, your clients will have to write custom code to interpret them.

HTML 5 forms support all four basic methods of HTTP’s uniform interface: GET, POST, PUT, and DELETE. I took advantage of this when designing my map application, if you’ll recall Example 6-3. This is the easiest HTML 5 feature to support today, especially since (as I’ll show in Chapter 11) most web browsers can already make PUT and DELETE requests.

There’s a proposal (not yet incorporated into HTML 5; see http://blog.welldesignedurls.org/2007/01/11/proposing-uri-templates-for-webforms-2/) that would allow forms to use URI Templates. Under this proposal, an application form can have its template attribute (not its action attribute) be a URI Template like http://search.example.com/search/{q}. It could then define q as a text field within the form. This would let you use an application form to “link” to http://search.example.com/search/jellyfish.

HTML 4 forms can specify more than one form element with the same name. This lets clients know they can submit the same key with 2 or 10 values: as many values as there are form elements. HTML 5 forms support the “repetition model,” a way of telling the client it’s allowed to submit the same key as many times as it wants. I used a simple repetition block in Example 5-11.

Finally, HTML 5 defines two new ways of serializing key-value pairs into representations: as plain text, or using a newly defined XML vocabulary. The content type for the latter is application/x-www-form+xml. This is not as big an advance as you might think. Form entities like input are still ways of getting data in the form of key-value pairs. These new serialization formats are just new ways of representing those key-value pairs. There’s still no way to show the client how to format a more complicated representation, unless the client can figure out the format from just the content type.

WADL

The Web Application Description Language is an XML vocabulary for expressing the behavior of HTTP resources (see the development site for the Java client). It was named by analogy with the Web Service Description Language, a different XML vocabulary used to describe the SOAP-based RPC-style services that characterize Big Web Services.

Look back to Service document” earlier in this chapter where I describe the Atom Publishing Protocol’s service documents. The representation of a service document is an XML document, written in a certain vocabulary, which describes a set of resources (APP collections) and the operations you’re allowed to perform on those resources. WADL is a standard vocabulary that can do for any resource at all what APP service documents do for APP collection resources.

You can provide a WADL file that describes every resource exposed by your service. This corresponds roughly to a WSDL file in a SOAP/WSDL service, and to the “site map” pages you see on the human web. Alternatively, you can embed a snippet of WADL in an XML representation of a particular resource, the way you might embed an HTML form in an HTML representation. The WADL snippet tells you how to manipulate the state of the resource.

As I said way back in Chapter 2, WADL makes it easy to write clients for web services. A WADL description of a resource can stand in for any number of programming-language interfaces to that resource: all you need is a WADL client written in the appropriate language. WADL abstracts away the details of HTTP requests, and the building and parsing of representations, without hiding HTTP’s uniform interface.

As of the time of writing, WADL is more talked about than used. There’s a Java client implementation, a rudimentary Ruby client, and that’s about it. Most existing WADL files are bootleg descriptions of other peoples’ RESTful and REST-RPC services.

WADL does better than HTML 5 as a hypermedia format. It supports URI Templates and every HTTP method there is. A WADL file can also tell the client to populate certain HTTP headers when it makes a request. More importantly, WADL can describe representation formats that aren’t just key-value pairs. You can specify the format of an XML representation by pointing to a schema definition. Then you can point out which parts of the document are most important by specifying key-value pairs where the “keys” are XPath statements. This is a small step, but an important one. With HTML you can only specify the format of an XML representation by giving it a different content type.

Of course, the “small step” only applies to XML. You can use WADL to say that a certain resource serves or accepts a JSON document, but unless that JSON document happens to be a hash (key-value pairs again!), there’s no way to specify what the JSON document ought to look like. This is a general problem which was solved in the XML world with schema definitions. It hasn’t been solved for other formats.

Describing a del.icio.us resource

Example 9-9 shows a Ruby client for the del.icio.us web service based on Ruby’s WADL library. It’s a reprint of the code from Clients Made Easy with WADL” in Chapter 2.

Example 9-9. A Ruby/WADL client for del.icio.us

#!/usr/bin/ruby
# delicious-wadl-ruby.rb
require 'wadl'

if ARGV.size != 2
  puts "Usage: #{$0} [username] [password]"
  exit
end
username, password = ARGV

# Load an application from the WADL file
delicious = WADL::Application.from_wadl(open("delicious.wadl"))

# Give authentication information to the application
service = delicious.v1.with_basic_auth(username, password)

begin
  # Find the "recent posts" functionality
  recent_posts = service.posts.recent

  # For every recent post...
  recent_posts.get.representation.each_by_param('post') do |post|
    # Print its description and URI.
    puts "#{post.attributes['description']}: #{post.attributes['href']}"
  end
rescue WADL::Faults::AuthorizationRequired
  puts "Invalid authentication information!"
end

The code’s very short but you can see what’s happening, especially now that we’re past Chapter 2 and I’ve shown you how resource-oriented services work. The del.icio.us web service exposes a resource that the WADL library identifies with v1. That resource has a subresource identified by posts.recent. If you recall the inner workings of del.icio.us from Chapter 2, you’ll recognize this as corresponding to the URI https://api.del.icio.us/v1/posts/recent. When you tell the WADL library to make a GET request to that resource, you get back some kind of response object which includes an XML representation. Certain parts of this representation, the posts, are especially interesting, and I process them as XML elements, extracting their descriptions and hrefs.

Let’s look at the WADL file that makes this code possible. I’ve split it into three sections: resource definition, method definition, and representation definition. Example 9-10 shows the resource definition. I’ve defined a nested set of WADL resources: recent inside posts inside v1. The recent WADL resource corresponds to the HTTP resource the del.icio.us API exposes at https://api.del.icio.us/v1/posts/recent.

Example 9-10. WADL file for del.icio.us: the resource

<?xml version="1.0"?>
<!-- This is a partial bootleg WADL file for the del.icio.us API. -->

<application xmlns="http://research.sun.com/wadl/2006/07">
 
  <!-- The resource -->
  <resources base="https://api.del.icio.us/">
    <doc xml:lang="en" title="The del.icio.us API v1">
      Post or retrieve your bookmarks from the social networking website.
      Limit requests to one per second.
    </doc>
    
    <resource path="v1">
      <param name="Authorization" style="header" required="true">
	<doc xml:lang="en">All del.icio.us API calls must be authenticated
	using Basic HTTP auth.</doc>
      </param>

      <resource path="posts">
	<resource path="recent">
	  <method href="#getRecentPosts" />
	</resource>
      </resource>     
    </resource>
  </resources>

That HTTP resource exposes a single method of the uniform interface (GET), so I define a single WADL method inside the WADL resource. Rather than define the method inside the resource tag and clutter up Example 9-10, I’ve defined it by reference. I’ll get to it next.

Every del.icio.us API request must include an Authorization header that encodes your del.icio.us username and password using HTTP Basic Auth. I’ve represented this with a param tag that tells the client it must provide an Authorization header. The param tag is the equivalent of an HTML form element: it tells the client about a blank to be filled in.[31]

Example 9-11 shows the definition of the method getRecentPosts. A WADL method corresponds to a request you might make using HTTP’s uniform interface. The id of the method can be anything, but its name is always the name of an HTTP method: here, “GET”. The method definition models both the HTTP request and response.

Example 9-11. WADL file for del.icio.us: the method

  <!-- The method -->
  <method id="getRecentPosts" name="GET">

    <doc xml:lang="en" title="Returns a list of the most recent posts." />
    
    <request>
      <param name="tag" style="form">
	<doc xml:lang="en" title="Filter by this tag." />
      </param>
      
      <param name="count" style="form" default="15">
	<doc xml:lang="en" title="Number of items to retrieve.">
	  Maximum: 100
	</doc>
      </param>
    </request>
    
    <response>
      <representation href="#postList" />
      <fault id="AuthorizationRequired" status="401" />
    </response>
  </method>

This particular request defines two more params: two more blanks to be filled in by the client. These are “query” params, which in a GET request means they’ll be tacked onto the query string—just like elements in an HTML form would be. These param definitions make it possible for the WADL client to access URIs like https://api.del.icio.us/v1/posts/recent?count=100 and https://api.del.icio.us/v1/posts/recent?tag=rest&count=20.

This WADL method defines an application form: not a way of manipulating resource state, but a pointer to possible new application states. This method tag tells the client about an infinite number of GET requests they can make to a set of related resources, without having to list infinitely many URIs. If this method corresponded to a PUT or POST request, its request might be a resource form, a way of manipulating resource state. Then it might describe a representation for you to send along with your request.

The response does describe a representation: the response document you get back from del.icio.us when you make one of these GET requests. It also describes a possible fault condition: if you submit a bad Authorization header, you’ll get a response code of 401 (“Unauthorized”) instead of a representation.

Take a look at Example 9-12, which defines the representation. This is WADL’s description of the XML document you receive when you GET https://api.del.icio.us/v1/posts/recent: a document like the one in Example 2-3.

Example 9-12. WADL file for del.icio.us: the representation

  <!-- The representation -->
  <representation id="postList" mediaType="text/xml" element="posts">
    <param name="post" path="/posts/post" repeating="true" />
  </representation>
  
</application>

The WADL description gives the most important points about this document: its content type is text/xml, and it’s rooted at the posts tag. The param tag points out that the the posts tag has a number of interesting children: the post tags. The param’s path attribute gives an XPath expression which the client can use on the XML document to fetch all the del.icio.us posts. My client’s call to each_by_param('post') runs that XPath expression against the document, and lets me operate on each matching element without having to know anything about XPath or the structure of the representation.

There’s no schema definition for this kind of XML representation: it’s a very simple document and del.icio.us just assumes you can figure out the format. But for the sake of demonstration, let’s pretend this representation has an XML Schema Definition (XSD) file. The URI of this imaginary definition is https://api.del.icio.us/v1/posts.xsd, and it defines the schema for the posts and post tags. In that fantasy situation, Example 9-13 shows how I might define the representation in terms of the schema file.

Example 9-13. WADL file for del.icious: the resource

<?xml version="1.0"?>
<!-- This is a partial bootleg WADL file for the del.icio.us API. -->

<application xmlns="http://research.sun.com/wadl/2006/07"
             xmlns:delicious="https://api.del.icio.us/v1/posts.xsd">

 <grammars>
  <include "https://api.del.icio.us/v1/posts.xsd" />
 </grammars>

 ...

  <representation id="postList" mediaType="text/xml" element="delicious:posts" />
 ...

</application>

I no longer need a param to say that this document is full of post tags. That information’s in the XSD file. I just have to define the representation in terms of that file. I do this by referencing the XSD file in this WADL file’s grammars, assigning it to the delicious: namespace, and scoping the representation’s element attribute to that namespace. If the client is curious about what a delicious:posts tag might contain, it can check the XSD. Even though the XSD completely describes the representation format, I might define some param tags anyway to point out especially important parts of the document.

Describing an APP collection

That was a pretty simple example. I used an application form to describe an infinite set of related resources, each of which responds to GET by sending a simple XML document. But I can use WADL to describe the behavior of any resource that responds to the uniform interface. If a resource serves an XML representation, I can reach into that representation with param tags: show where the interesting bits of data are, and where the links to other resources can be found.

Earlier I compared WADL files to the Atom Publishing Protocol’s service documents. Both are XML vocabularies for describing resources. Service documents describe APP collections, and WADL documents describe any resource at all. You’ve seen how a service document describes a collection (Example 9-6). What would a WADL description of the same resources look like?

As it happens, the WADL standard gives just this example. Section A.2 of the standard shows an APP service document and then a WADL description of the same resources. I’ll present a simplified version of this idea here.

The service document in Example 9-6 describes three Atom collections. One accepts new Atom entries via POST, and the other two accept image files. These collections are pretty similar. In an object-oriented system I might factor out the differences by defining a class hierarchy. I can do something similar in WADL. Instead of defining all three resources from scratch, I’m going to define two resource types. Then it’ll be simple to define individual resources in terms of the types (see Example 9-14).

Example 9-14. A WADL file for APP: resource types

<?xml version="1.0"?>
<!-- This is a description of two common types of resources that respond
     to the Atom Publishing Protocol. -->

<application xmlns="http://research.sun.com/wadl/2006/07"
             xmlns:app="http://purl.org/atom/app">

  <!-- An Atom collection accepts Atom entries via POST. -->
  <resource_type id="atom_collection">
    <method href="#getCollection" />
    <method href="#postNewAtomMember" />
  </resource_type>

  <!-- An image collection accepts image files via POST. -->
  <resource_type id="image_collection">
    <method href="#getCollection" />
    <method href="#postNewImageMember" />
  </resource_type>

There are my two resource types: the Atom collection and the image collection. These don’t correspond to any specific resources: they’re equivalent to classes in an object-oriented design. Both “classes” support a method identified as getCollection, but the Atom collection supports a method postNewAtomMember where the image collection supports postNewImageMember. Example 9-15 shows those three methods:

Example 9-15. A WADL file for APP: methods

  <!-- Three possible operations on resources. -->
  <method name="GET" id="getCollection">
    <response>
      <representation href="#feed" />
    </response>
  </method>

  <method name="POST" id="postNewAtomMember">
    <request>
      <representation href="#entry" />
    </request>
  </method>

  <method name="POST" id="postNewImageMember">
    <request>
      <representation id="image"  mediaType="image/*" />
      <param name="Slug" style="header" />
    </request>
  </method>

The getCollection WADL method is revealed as a GET operation that expects an Atom feed (to be described) as its representation. The postNewAtomMember method is a POST operation that sends an Atom entry (again, to be described) as its representation. The postNewImageMember method is also a POST operation, but the representation it sends is an image file, and it knows how to specify a value for the HTTP header Slug.

Finally, Example 9-16 describes the two representations: Atom feeds and atom entries. I don’t need to describe these representations in great detail because they’re already described in the XML Schema Document for Atom: I can just reference the XSD file. But I’m free to annotate the XSD by defining param elements that tell a WADL client about the links between resources.

Example 9-16. A WADL file for APP: the representations

  <!-- Two possible XML representations. -->
  <representation id="feed" mediaType="application/atom+xml"
		  element="atom:feed" />

  <representation id="entry" mediaType="application/atom+xml"
		  element="atom:entry" />

</application>

I can make the file I just defined available on the Web: say, at http://www.example.com/app-resource-types.wadl. Now it’s a resource. I can use it in my services by referencing its URI. So can anyone else. It’s now possible to define certain APP collections in terms of these resource types. My three collections are defined in just a few lines in Example 9-17.

Example 9-17. A WADL file for a set of APP collections

<?xml version="1.0"?>
<!-- This is a description of three "collection" resources that respond
     to the Atom Publishing Protocol. -->

<application xmlns="http://research.sun.com/wadl/2006/07"
             xmlns:app="http://purl.org/atom/app">
  <resources base="http://www.example.com/">
    <resource path="RESTfulNews" 
     type="http://www.example.com/app-resource-types.wadl#atom_collection" />
    <resource path="samruby/photos" 
     type="http://www.example.com/app-resource-types.wadl#image_collection" />
    <resource path="leonardr/photos" 
     type="http://www.example.com/app-resource-types.wadl#image_collection"/>
  </resources>
</application>

The Atom Publishing Protocol is popular because it’s such a general interface. The major differences between two APP services are described in the respective service documents. A generic APP client can read these documents and reprogram itself to act as a client for many different services. But there’s an even more general interface: the uniform interface of HTTP. An APP service document uses a domain-specific XML vocabulary, but hypermedia formats like HTML and WADL can be used to describe any web service at all. Their clients can be even more general than APP clients.

Hypermedia is how one service communicates the ways it differs from other services. If that intelligence is embedded in hypermedia, the programmer needs to hardwire less of it in code. More importantly, hypermedia gives you access to the link: the second most important web technology after the URI. The potential of REST will not be fully exploited until web services start serving their representations as link-rich hypermedia instead of plain media.

Is WADL evil?

In Chapter 10 I’ll talk about how WSDL turned SOAP from a simple XML envelope format to a name synonymous with the RPC style of web services. WSDL abstracts away the details of HTTP requests and responses, and replaces them with a model based on method calls in a programming language. Doesn’t WADL do the exact same thing? Should we worry that WADL will do to plain-HTTP web services what WSDL did to SOAP web services: tie them to the RPC style in the name of client convenience?

I think we’re safe. WADL abstracts away the details of HTTP requests and responses, but—this is the key point—it doesn’t add any new abstraction on top. Remember, REST isn’t tied to HTTP. When you abstract HTTP away from a RESTful service, you’ve still got REST. A resource-oriented web service exposes resources that respond to a uniform interface: that’s REST. A WADL document describes resources that respond to a uniform interface: that’s REST. A program that uses WADL creates objects that correspond to resources, and accesses them with method calls that embody a uniform interface: that’s REST. RESTfulness doesn’t live in the protocol. It lives in the interface.

About the worst you can do with WADL is hide the fact that a service responds to the uniform interface. I’ve deliberately not shown you how to do this, but you should be able to figure it out. You may need to do this if you’re writing a WADL file for a web application or REST-RPC hybrid service that doesn’t respect the uniform interface.

I’m fairly sure that WADL itself won’t tie HTTP to an RPC model, the way WSDL did to SOAP. But what about those push-button code generators, the ones that take your procedure-call-oriented code and turn it into a “web service” that only exposes one URI? WADL makes you define your resources, but what if tomorrow’s generator creates a WADL file that only exposes a single “resource”, the way an autogenerated WSDL file exposes a single “endpoint”?

This is a real worry. Fortunately, WADL’s history is different from WSDL’s. WSDL was introduced at a time when SOAP was still officially associated with the RPC style. But WADL is being introduced as people are becoming aware of the advantages of REST, and it’s marketed as a way to hide the details while keeping the RESTful interface. Hopefully, any tool developers who want to make their tools support WADL will also be interested in making their tools support RESTful design.



[31] Marc Hadley, the primary author of the WADL standard, is working on more elegant ways of representing the need to authenticate.

The best content for your career. Discover unlimited learning on demand for around $1/day.