You are previewing RESTful Web Services Cookbook.

RESTful Web Services Cookbook

Cover of RESTful Web Services Cookbook by Subbu Allamaraju Published by O'Reilly Media, Inc.
  1. RESTful Web Services Cookbook
    1. SPECIAL OFFER: Upgrade this ebook with O’Reilly
    2. Preface
      1. Scope of the Book
      2. Companion Material
      3. How This Book Is Organized
      4. Conventions Used in This Book
      5. Using Code Examples
      6. Safari® Books Online
      7. How to Contact Us
      8. Acknowledgments
      9. Mike Amundsen’s Contribution
    3. 1. Using the Uniform Interface
      1. 1.1. How to Keep Interactions Visible
      2. 1.2. When to Trade Visibility
      3. 1.3. How to Maintain Application State
      4. 1.4. How to Implement Safe and Idempotent Methods on the Server
      5. 1.5. How to Treat Safe and Idempotent Methods in Clients
      6. 1.6. When to Use GET
      7. 1.7. When to Use POST
      8. 1.8. How to Create Resources Using POST
      9. 1.9. When to Use PUT to Create New Resources
      10. 1.10. How to Use POST for Asynchronous Tasks
      11. 1.11. How to Use DELETE for Asynchronous Deletion
      12. 1.12. When to Use Custom HTTP Methods
      13. 1.13. When and How to Use Custom HTTP Headers
    4. 2. Identifying Resources
      1. 2.1. How to Identify Resources from Domain Nouns
      2. 2.2. How to Choose Resource Granularity
      3. 2.3. How to Organize Resources into Collections
      4. 2.4. When to Combine Resources into Composites
      5. 2.5. How to Support Computing/Processing Functions
      6. 2.6. When and How to Use Controllers to Operate on Resources
    5. 3. Designing Representations
      1. 3.1. How to Use Entity Headers to Annotate Representations
      2. 3.2. How to Interpret Entity Headers
      3. 3.3. How to Avoid Character Encoding Mismatch
      4. 3.4. How to Choose a Representation Format and a Media Type
      5. 3.5. How to Design XML Representations
      6. 3.6. How to Design JSON Representations
      7. 3.7. How to Design Representations of Collections
      8. 3.8. How to Keep Collections Homogeneous
      9. 3.9. How to Use Portable Data Formats in Representations
      10. 3.10. When to Use Entity Identifiers
      11. 3.11. How to Encode Binary Data in Representations
      12. 3.12. When and How to Serve HTML Representations
      13. 3.13. How to Return Errors
      14. 3.14. How to Treat Errors in Clients
    6. 4. Designing URIs
      1. 4.1. How to Design URIs
      2. 4.2. How to Use URIs As Opaque Identifiers
      3. 4.3. How to Let Clients Treat URIs As Opaque Identifiers
      4. 4.4. How to Keep URIs Cool
    7. 5. Web Linking
      1. 5.1. How to Use Links in XML Representations
      2. 5.2. How to Use Links in JSON Representations
      3. 5.3. When and How to Use Link Headers
      4. 5.4. How to Assign Link Relation Types
      5. 5.5. How to Use Links to Manage Application Flow
      6. 5.6. How to Deal with Ephemeral URIs
      7. 5.7. When and How to Use URI Templates
      8. 5.8. How to Use Links in Clients
    8. 6. Atom and AtomPub
      1. 6.1. How to Model Resources Using Atom
      2. 6.2. When to Use Atom
      3. 6.3. How to Use AtomPub Service and Category Documents
      4. 6.4. How to Use AtomPub for Feed and Entry Resources
      5. 6.5. How to Use Media Resources
    9. 7. Content Negotiation
      1. 7.1. How to Indicate Client Preferences
      2. 7.2. How to Implement Media Type Negotiation
      3. 7.3. How to Implement Language Negotiation
      4. 7.4. How to Implement Character Encoding Negotiation
      5. 7.5. How to Support Compression
      6. 7.6. When and How to Send the Vary Header
      7. 7.7. How to Handle Negotiation Failures
      8. 7.8. How to Use Agent-Driven Content Negotiation
      9. 7.9. When to Support Server-Driven Negotiation
    10. 8. Queries
      1. 8.1. How to Design URIs for Queries
      2. 8.2. How to Design Query Responses
      3. 8.3. How to Support Query Requests with Large Inputs
      4. 8.4. How to Store Queries
    11. 9. Web Caching
      1. 9.1. How to Set Expiration Caching Headers
      2. 9.2. When to Set Expiration Caching Headers
      3. 9.3. When and How to Use Expiration Headers in Clients
      4. 9.4. How to Support Caching for Composite Resources
      5. 9.5. How to Keep Caches Fresh and Warm
    12. 10. Conditional Requests
      1. 10.1. How to Generate Last-Modified and ETag Headers
      2. 10.2. How to Implement Conditional GET Requests in Servers
      3. 10.3. How to Submit Conditional GET and HEAD Requests from Clients
      4. 10.4. How to Implement Conditional PUT Requests in Servers
      5. 10.5. How to Implement Conditional DELETE Requests in Servers
      6. 10.6. How to Make Unconditional GET Requests from Clients
      7. 10.7. How to Submit Conditional PUT and DELETE Requests from Clients
      8. 10.8. How to Make POST Requests Conditional
      9. 10.9. How to Generate One-Time URIs
    13. 11. Miscellaneous Writes
      1. 11.1. How to Copy a Resource
      2. 11.2. How to Merge Resources
      3. 11.3. How to Move a Resource
      4. 11.4. When to Use WebDAV Methods
      5. 11.5. How to Support Operations Across Servers
      6. 11.6. How to Take Snapshots of Resources
      7. 11.7. How to Undo Resource Updates
      8. 11.8. How to Refine Resources for Partial Updates
      9. 11.9. How to Use the PATCH Method
      10. 11.10. How to Process Similar Resources in Bulk
      11. 11.11. How to Trigger Bulk Operations
      12. 11.12. When to Tunnel Multiple Requests Using POST
      13. 11.13. How to Support Batch Requests
      14. 11.14. How to Support Transactions
    14. 12. Security
      1. 12.1. How to Use Basic Authentication to Authenticate Clients
      2. 12.2. How to Use Digest Authentication to Authenticate Clients
      3. 12.3. How to Use Three-Legged OAuth
      4. 12.4. How to Use Two-Legged OAuth
      5. 12.5. How to Deal with Sensitive Information in URIs
      6. 12.6. How to Maintain the Confidentiality and Integrity of Representations
    15. 13. Extensibility and Versioning
      1. 13.1. How to Maintain URI Compatibility
      2. 13.2. How to Maintain Compatibility of XML and JSON Representations
      3. 13.3. How to Extend Atom
      4. 13.4. How to Maintain Compatibility of Links
      5. 13.5. How to Implement Clients to Support Extensibility
      6. 13.6. When to Version
      7. 13.7. How to Version RESTful Web Services
    16. 14. Enabling Discovery
      1. 14.1. How to Document RESTful Web Services
      2. 14.2. How to Use OPTIONS
    17. A. Additional Reading
      1. Books
      2. References
    18. B. Overview of REST
      1. Uniform Resource Identifiers
      2. Resources
      3. Representations
      4. Uniform Interface
      5. Hypermedia and Application State
    19. C. HTTP Methods
      1. OPTIONS
      2. GET
      3. HEAD
      4. POST
      5. PUT
      6. DELETE
      7. TRACE
    20. D. Atom Syndication Format
      1. Key Elements of Feeds and Entries
      2. Other Atom Elements to Consider
    21. E. Link Relation Registry
      1. alternate
      2. appendix
      3. bookmark
      4. chapter, section, subsection
      5. contents
      6. copyright
      7. current
      8. describedby
      9. edit
      10. edit-media
      11. enclosure
      12. first, last, next, next-archive, prev, previous, prev-archive, start
      13. glossary
      14. help
      15. index
      16. license
      17. payment
      18. related
      19. replies
      20. self
      21. service
      22. stylesheet
      23. up
      24. via
    22. Index
    23. About the Author
    24. Colophon
    25. SPECIAL OFFER: Upgrade this ebook with O’Reilly
O'Reilly logo

1.10. How to Use POST for Asynchronous Tasks

HTTP is a synchronous and stateless protocol. When a client submits a request to a server, the client expects an answer, whether the answer is a success or a failure. But this does not mean that the server must finish processing the request before returning a response. For example, in a banking application, when you initiate an account transfer, the transfer may not happen until the next business day, and the client may be required to check for the status later. This recipe discusses how to use this method to process requests asynchronously.


You want to know how to implement POST requests that take too long to complete.


On receiving a POST request, create a new resource, and return status code 202 (Accepted) with a representation of the new resource. The purpose of this resource is to let a client track the status of the asynchronous task. Design this resource such that its representation includes the current status of the request and related information such as a time estimate.

When the client submits a GET request to the task resource, do one of the following depending on the current status of the request:

Still processing

Return response code 200 (OK) and a representation of the task resource with the current status.

On successful completion

Return response code 303 (See Other) and a Location header containing a URI of a resource that shows the outcome of the task.

On task failure

Return response code 200 (OK) with a representation of the task resource informing that the resource creation has failed. Clients will need to read the body of the representation to find the reason for failure.


Consider an image-processing web service offering services such as file conversions, optical character recognition, image cleanup, etc. To use this service, clients upload raw images. Depending on the nature and size of images uploaded and the current server load, the server may take from a few seconds up to several hours to process each image. Upon completion, client applications can view/download processed images.

Let’s start with the client submitting a POST request to initiate a new image-processing task:

# Request
POST /images/tasks HTTP/1.1
Content-Type: multipart/related; boundary=xyz

Content-Type: application/xml;charset=UTF-8


Content-Type: image/png



In this example, the client uses a multipart message, with the first part containing an XML document describing the kind of image-processing operations the server needs to perform and the second part containing the image to be processed.

Upon ensuring that the contents are valid and that the given image-processing request can be honored, let the server create a new task resource:

# Response
HTTP/1.1 202 Accepted  1
Content-Type: application/xml;charset=UTF-8
Date: Sun, 13 Sep 2009 01:49:27 GMT

<status xmlns:atom="">
  <atom:link href="" rel="self"/>
  <message xml:lang="en">Your request has been accepted for processing.</message>
  <ping-after>2009-09-13T01:59:27Z</ping-after> 2

Response code indicating that the server accepted the request for processing


A hint to check for the status at a later time

The client can subsequently send a GET request to this task resource. If the server is still processing the task, it can return the following response:

# Request
GET /images/task/1 HTTP/1.1

# Response
HTTP/1.1 200 OK
Content-Type: application/xml;charset=UTF-8

<status xmlns:atom="">
  <atom:link href="" rel="self"/>
  <message xml:lang="en">Your request is currently being processed.</message>


See Recipe 3.9 to learn the rationale behind the choice of the date-time value for the ping-after element.

After the server successfully completes image processing, it can redirect the client to the result. In this example, the result is a new image resource:

# Request
GET /images/task/1 HTTP/1.1

# Response
HTTP/1.1 303 See Other  1

<status xmlns:atom="">
  <atom:link href="" rel="self"/>
  <message xml:lang="en">Your request has been processed.</message>

See the target resource for the result.


The response code 303 merely states that the result exists at the URI indicated in the Location header. It does not mean that the resource at the request URI (e.g., has moved to a new location.

This representation informs the client that it needs to refer to for the result. If, on the other hand, the server fails to complete the task, it can return the following:

# Request
GET /images/task/1 HTTP/1.1

# Response
HTTP/1.1 200 OK
Content-Type: application/xml;charset=UTF-8

<status xmlns:atom="">
  <atom:link href="" rel="self"/>
  <message xml:lang="en">Failed to complete the request.</message>
  <detail xml:lang="en">Invalid image format.</detail>

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