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

Cross-Browser Issues and Ajax Libraries

As always when web browsers are involved, different clients have different levels of support for XMLHttpRequest. And as always seems to happen, Internet Explorer is the major outlier. This isn’t quite fair, because XMLHttpRequest was a Microsoft invention and Internet Explorer was the first browser to support Ajax at all. But until the release of Internet Explorer 7, Ajax was implemented as Windows-specific technology: an ActiveX control called XMLHttp.

The cross-platform Mozilla project adopted the API of the XMLHttp control, but implemented it as a class you could instantiate directly from JavaScript. Other browsers followed this lead, and all current browsers now use the XMLHttpRequest name (including the new Internet Explorer). But old versions of Internet Explorer still make up a big portion of the user base, so cross-browser issues are still a problem.

Example 11-7 is a JavaScript function that always creates an object that acts like an XMLHttpRequest, even though under the covers it may be an ActiveX control. It was written by Bret Taylor and comes from his site at http://ajaxcookbook.org/.

Example 11-7. A cross-browser wrapper for XMLHttpRequest

function createXMLHttpRequest() { 
  if (typeof XMLHttpRequest != "undefined") { 
    return new XMLHttpRequest();
  } else if (typeof ActiveXObject != "undefined") { 
    return new ActiveXObject("Microsoft.XMLHTTP"); 
  } else { 
    throw new Error("XMLHttpRequest not supported");
  }
}

This function is a drop-in replacement for the XMLHttpRequest constructor in Example 11-3, instead of this:

request = new XMLHttpRequest();

you might write this:

request = createXMLHttpRequest();

I know of two other major cross-browser issues. First, the Safari browser doesn’t support the PUT and DELETE methods. If you want your service to be accessible from Safari, you’ll need to allow your clients to simulate PUT and DELETE requests with overloaded POST. Second, Microsoft Internet Explorer caches successful responses indefinitely. This makes it look to the user like your resources haven’t changed, even when they have. The best way to get around this is to send proper ETag response headers with your representations, or to disable caching altogether with Cache-Control. You can use the XMLHttpRequest test suite to find out about more minor cross-browser quirks.

Because Ajax is a very important niche for JavaScript applications, some JavaScript libraries include wrappers for hiding the differences between browsers. I’m not going to cover these frameworks in detail, because they act more as standard libraries for JavaScript than tools for building web service clients. I will show how to make simple HTTP requests with two popular libraries, Prototype and Dojo. Another popular library, script.aculo.us, is based on Prototype.

Prototype

Prototype introduces three classes for making HTTP requests:

  • Ajax.Request: a wrapper around XMLHttpRequest that takes care of cross-browser issues and can call different JavaScript functions on the request’s success or failure. The actual XMLHttpRequest object is available as the transport member of the Request object, so responseXML will be through request.transport.responseXML.

  • Ajax.Updater: a subclass of Request that makes an HTTP request and inserts the response document into a specified element of the DOM.

  • Ajax.PeriodicalUpdater, which makes the same HTTP request at intervals, refreshing a DOM element each time.

I’ve implemented the del.icio.us Ajax client in Prototype, and it was mostly the same as the client I showed you starting in Example 11-1. The code snippet below mostly replaces the code in Example 11-3 where the XMLHttpRequest constructor used to be. Note the new script tag, the use of request.transport instead of request, and the use of Prototype’s onFailure hook to signal a failure (such as an authorization failure) to the user.

Example 11-8. A portion of ajax-delicious-prototype.html

...
<script src="prototype.js"></script> 
<script type="text/javascript">
  ... 
  var request = new Ajax.Request("https://api.del.icio.us/v1/posts/recent", 
                                 {method: 'get', onSuccess: populateLinkList, 
                                 onFailure: reportFailure});
  function reportFailure() { 
    setMessage("An error occured: " + request.transport.status);
  }

  // Called when the HTTP request has completed. 
  function populateLinkList() { 
    setMessage("Request complete."); 
    if (netscape.security.PrivilegeManager.enablePrivilege) {
      netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserRead");
    }

    posts = request.transport.responseXML.getElementsByTagName("post");
    ...

In its quest to simplify XMLHttpRequest, Prototype hides some of the features. You can’t set request headers, or specify a username and password for basic HTTP auth. So even if you’re using Prototype, you might want to keep around a snippet of code like the one in Example 11-7. On the other hand, the Prototype implementation of the del.icio.us client doesn’t need the username and password text fields at all: it just needs a button. The end user’s browser will prompt her anyway for her del.icio.us username and password.

Dojo

The Dojo library provides a uniform API that not only hides the differences between browsers when it comes to XMLHttpRequest, it hides the difference between XMLHttpRequest and other ways of getting the browser to send an HTTP request. These “transports” include tricks that use HTML tags, such as JoD. All the variants on XMLHttpRequest are kept in the dojo.io.XMLHttp transport class. For all transports, the bind method is the one that makes the HTTP request.

As with Prototype, I’ve implemented the del.icio.us Ajax client with Dojo, and it’s mostly the same as the original, except for the section in Example 11-3 where the XMLHttpRequest constructor used to be. Example 11-9 shows the relevant portions of ajax-delicious-dojo.html.

Example 11-9. Some portions of ajax-delicious-dojo.html

...
  <script src="dojo/dojo.js"></script>
  <script type="text/javascript">
    ...
    dojo.require("dojo.io.*");
    dojo.io.bind({ url: "https://api.del.icio.us/v1/posts/recent", load:
                   populateLinkList, error: reportFailure });

    function reportFailure(type, error) { 
      setMessage("An error occured: " + error.message); 
    }

    // Called when the HTTP request has completed. 
    function populateLinkList(type, data, request) { 
      setMessage("Request complete.");
      if (netscape.security.PrivilegeManager.enablePrivilege) {
        netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserRead");
      }

      posts = request.responseXML.getElementsByTagName("post");
    ...

The error-handling function is passed a dojo.io.Error object with members called number and message. You can ignore the first argument: it’s always “error.” You can also ignore the first argument to the success-handling function (it’s always “load”). The second argument, called data above, is an interface to use Dojo’s DOM manipulation interface. If you want to use the XMLHttpRequest interface instead, you can ignore that argument too.

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