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. 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 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

Chapter 12. Frameworks for RESTful Services

As the REST design philosophy becomes more popular, new frameworks are springing up to make RESTful design easy. Existing frameworks are acquiring RESTful modes and features. This, in turn, drives additional interest in REST. In this chapter, I and a few knowledgeable contributors show you how to write resource-oriented services in three popular frameworks: Ruby on Rails, Restlet (for Java), and Django (for Python).

Back in Chapter 1 I said that REST isn’t an architecture, but a way of judging architectures. The Resource-Oriented Architecture is an architecture: it imposes constraints on your thinking that make it easy for you to break a problem down into RESTful resources. But these resources still only exist on an abstract level. They aren’t real until you expose them through specific web services.

If you’re writing a service from scratch (say, as a CGI script), you can translate your resources into code however you like. But most services aren’t written from scratch: they’re written using a web framework. A REST-aware web framework imposes constraints on your programming that make it easy for you to implement RESTful resources in a specific programming language. In this chapter I’ll show you how to integrate the lessons of this book with real frameworks.

Ruby on Rails

The simplifying assumption is the main driver of the success of Ruby on Rails. Rather than give you a large number of tools for accomplishing any task you can think of, Rails gives you one way to accomplish a wide variety of common tasks. You can create a Rails application very quickly if you’re trying to expose data from a relational database, if your database tables have certain names and structure, if you care to work with a Model-View-Controller architecture, and so on. Because so many problems in the web application domain fit these assumptions, the effect is rarely onerous and often liberating.

Earlier versions of Rails exposed a textbook REST-RPC hybrid architecture, but Rails 1.2 focuses on a more RESTful design. Perhaps this was inevitable: HTTP’s uniform interface is just another simplifying assumption. I’ve already shown in Chapter 7 how Rails can be used to make sophisticated RESTful services in very little code. In this section, I take a step back and describe the RESTful architecture of Rails in more general terms.


When an HTTP request comes in, Rails analyzes the requested URI and routes the request to the appropriate controller class. As shown in Example 12-1, the file config/routes.rb tells Rails how to handle certain requests.

Example 12-1. A simple routes.rb file

# routes.rb
ActionController::Routing::Routes.draw do |map|
  map.resources :weblogs do |weblog|
    weblog.resources :entries

A config/routes.rb file can get fairly sophisticated. The one in Chapter 7 is relatively complex: I had a lot of resources, and I had to fight the simplifying assumptions a little bit to get the URI structure I wanted. Example 12-1 shows a simpler routes.rb file that buys into the simplifying assumptions.

That file declares the existence of two controller classes (WeblogsController and EntriesController), and tells Rails how to route incoming requests to those classes. WeblogsController handles requests for the URI /weblogs, and for all URIs of the form /weblogs/{id}. When present, the path variable {id} is made available as params[:id].

EntriesController handles requests for the URI /weblogs/{weblog_id}/entries, and all URIs of the form /weblogs/{weblog_id}/entries/{id}. The path variable {weblog_id} is made available as params[:weblog_id], and {id}, if present, is made available as params[:id].

Variables like {id} and {weblog_id} are typically used to associate a resource with a particular object in the system. They often correspond to database IDs, and get plugged into the ActiveRecord find method. In my clone I tried to give them descriptive names like {username}, and used them as identifying names rather than IDs.

Resources, Controllers, and Views

As I showed in Chapter 7, every Rails controller might expose two kinds of resources. You can have a single “list” or “factory” resource, which responds to GET and/or POST requests, and you can have a large number of “object” resources, which respond to GET, PUT, and/or DELETE. The list resource often corresponds to a database table, and the object resources to the rows in the table.

Each controller is a Ruby class, so “sending” an HTTP request to a class means calling some particular method. Rails defines five standard methods per controller, as well as exposing two special view templates through HTTP GET. For illustration’s sake, here are the seven HTTP requests made possible by my call to map.resources :weblogs back in Example 12-1:

  • GET /weblogs: A list of the weblogs. Rails calls the WeblogsController#index method.

  • GET /weblogs/new: The form for creating a new weblog. Rails renders the view in app/view/welogs/new.rhtml. This view is a hypermedia file describing what sort of HTTP request the client must make to create a new weblog.

    In other words, this is an HTML form (though it could also be a small WADL file). The form says that to create a new weblog, the client should send a POST request to /weblogs (see below). It also tells the client how to format its representation of the new weblog, so that the server can understand it.

  • POST /weblogs: Create a new weblog. Rails calls the WeblogsController#create method.

  • GET /weblogs/{id}: A weblog. Rails calls WeblogsController#show.

  • GET /weblogs/{id};edit: The form for editing a weblog’s state. Rails renders the view in app/view/welogs/edit.rhtml. This view is a hypermedia file describing what sort of HTTP request the client must make if it wants to edit a weblog’s state.

    In practice, this means the view is an HTML form, or short WADL file. The hypermedia file tells the client how to send or simulate a PUT request to /weblogs/{id}.

  • PUT /weblogs/{id}: Change a weblog’s state. Rails calls WeblogsController#update. The “state” here is the state associated with this particular resource: things like the weblog’s name and the author’s contact information. Individual entries are exposed as separate resources.

  • DELETE /weblogs/{id}: Delete a weblog. Rails calls WeblogsController#delete.

You probably won’t expose all seven access points in every controller you create. In particular, you probably won’t use the special views unless you’re running your web service as a web site. This is no problem: just don’t implement the methods or view files you don’t intend to expose.

Outgoing Representations

Rails makes it easy to send different representations of a resource based on the client’s request. Example 12-2 shows some hypothetical Ruby code that renders three different representations of a weblog. Which representation is sent depends on the URI the client accessed, or on the value it provided in the Accept header. A client will get the HTML rendition if it accesses /weblogs/1.html, but if the client accesses /weblogs/1.png instead, the service will send a graphical PNG rendition. The respond_to function takes care of interpreting the client’s capabilities and desires. All you have to do is implement the supported options, in order of precedence.

Example 12-2. Serving one of several representations

respond_to do |format|
  format.html { render :template => 'weblogs/show' }
  format.xml  { render :xml => weblog.to_xml }
  format.png  { render :text => weblog.generate_image, 
                       :content_type => "image/png" }

Two especially common representation formats are HTML and the ActiveResource XML serialization format. HTML representations are expressed using Rails views, as they would be in a human-oriented web application. To expose an ActiveRecord object as an XML document, you can just call to_xml on an object or a list of objects.

Rails plugins make it easy to expose data in other representation formats. In Chapter 7, I installed the atom-tools Ruby gem so that I could render lists of bookmarks as Atom feeds. In Example 7-8 I have a respond_to code block, containing clauses which distinguish between requests for Atom and generic XML representations.

Incoming Representations

Rails sees its job as turning an incoming representation into a bunch of key-value pairs, and making those key-value pairs available through the params hash. By default, it knows how to parse form-encoded documents of the sort sent by web browsers, and simple XML documents like the ones generated by to_xml.

If you want to get this kind of action for your own incoming representations, you can add a new Proc object to ActionController::Base.param_parsers hash. The Proc object is a block of code whose job is to process an incoming representation of a certain media type. For details, see the Rails documentation for the param_parsers hash.

Web Applications as Web Services

Rails 1.2 does an excellent job of merging the human web and the programmable web. As I showed in Chapter 3, Rails comes with a code generator called scaffold which exposes a database table as a set of resources. You can access the resources with a web browser, or with a web service client like ActiveResource.

If you use a web browser to access a scaffold service, you’re served HTML representations of the database objects, and HTML forms for manipulating them (generated by the new.rhtml and edit.rhtml I mentioned earlier). You can create, modify, and delete the resources by sending new representations in form-encoded format. PUT and DELETE requests are simulated through overloaded POST.

If you use a web service client to access a scaffold service, you’re served XML representations of the database objects. You manipulate objects by modifying the XML documents and sending then back with PUT. Non-overloaded POST and DELETE work like you’d expect.

There’s no more compelling example of the human web’s basic similarity to the programmable web. In Chapter 7 I largely ignored this aspect of Rails for space reasons, but it makes a compelling argument for using Rails if you’re designing a web site and a web service to do the same thing. Rails makes it easy to expose them both as aspects of the same underlying code.

The Rails/ROA Design Procedure

The following list is a modified version of the generic design procedure from Chapter 6. It’s what I used, unofficially, to design the service in Chapter 7. The main difference is that you divide the dataset into controllers and the controllers into resources, rather than dividing the dataset into resources. This reduces the chance that you’ll end up with resources that don’t fit Rails’s controller system.

  1. Figure out the dataset.

  2. Assign the dataset to controllers.

    For each controller:

    1. Does this controller expose a list or factory resource?

    2. Does this controller expose a set of object resources?

    3. Does this controller expose a creation form or editing form resource?

      For the list and object resources:

      • Design the representation(s) accepted from the client, if different from the Rails standard.

      • Design the representation(s) served to the client.

      • Connect this resource to existing resources.

      • Consider the typical course of events: what’s supposed to happen? The database-backed control flow from Chapter 9 should help here.

      • Consider error conditions: what might go wrong? Again, you can often use the database-backed control flow.

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