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

Chapter 4. Designing URIs

URIs are identifiers of resources that work across the Web. A URI consists of a scheme (such as http and https), a host (such as, a port number followed by a path with one or more segments (such as /users/1234), and a query string. In this chapter, our focus is on designing URIs for RESTful web services:

Recipe 4.1

Use this recipe to learn some commonly practiced URI design conventions.

Recipe 4.2

Use this recipe to learn some dos and don’ts to keep URIs as opaque identifiers.

Recipe 4.3

Treating URIs as opaque identifiers helps decouple clients from servers. This recipe shows techniques that the server can employ to help clients treat URIs as opaque.

Recipe 4.4

Since URIs are a key part of the interface between clients and servers, it is important to keep them cool, i.e., stable and permanent. Use this recipe to learn some practices to help keep URIs cool.

4.1. How to Design URIs

URIs are opaque resource identifiers. In most cases, clients need not be concerned with how a server designs its URIs. However, following common conventions when designing URIs has several advantages:

  • URIs that support convention are usually easy to debug and manage.

  • Servers can centralize code to extract data from request URIs.

  • You can avoid spending valuable design and implementation time inventing new conventions and rules for processing URIs.

  • Partitioning the server’s URIs across domains, subdomains, and paths gives you operational flexibility for load distribution, monitoring, routing, and security.


You want to know the best practices to design URIs for resources.


  • Use domains and subdomains to logically group or partition resources for localization, distribution, or to enforce various monitoring or security policies.

  • Use the forward-slash separator (/) in the path portion of the URI to indicate a hierarchical relationship between resources.

  • Use the comma (,) and semicolon (;) to indicate nonhierarchical elements in the path portion of the URI.

  • Use the hyphen (-) and underscore (_) characters to improve the readability of names in long path segments.

  • Use the ampersand (&) to separate parameters in the query portion of the URI.

  • Avoid including file extensions (such as .php, .aspx, and .jsp) in URIs.


URI design is just one aspect of implementing RESTful applications. Here are some conventions to consider when designing URIs.


As important as URI design is to the success of your web service, it is just as important to keep the time spent in URI design to a minimum. Focus on consistency of URIs instead.

Domains and subdomains

A logical partition of URIs into domains and subdomains provides several operational benefits for server administration. Make sure to use logical names for subdomains while partitioning URIs. For example, the server could offer localized representations via different subdomains, as in the following: 

Another example is, partition based on the class of clients. 

In this example, the server offers two subdomains, one for browsers and the other for custom clients. Such partitioning may let the server allocate different hardware or apply different routing, monitoring, or security policies for HTML and non-HTML representations.

Forward-slash separator

By convention, the forward slash (/) character is used to convey hierarchical relationships. This is not a hard and fast rule, but most users assume this when they scan URIs. In fact, the forward slash is the only character mentioned in RFC 3986 as typically indicating a hierarchical relationship. For example, all the following URIs convey a hierarchical association between path segments: 

Some web services may use a trailing forward slash for collection resources. Use such conventions with care since some development frameworks may incorrectly remove such slashes or add trailing slashes during URI normalization.

Underscore and hyphen

If you want to make your URIs easy for humans to scan and interpret, use the underscore (_) or hyphen (-) character: 

There is no reason to favor one over the other. For the sake of consistency, pick one and use it consistently.


Use the ampersand character (&) to separate parameters in the query portion of the URI: 

In the first URI shown, the parameters are draftmode and landscape. The second URI has the parameters word=Antarctica and limit=30.

Comma and semicolon

Use the comma (,) and semi-colon (;) characters to indicate nonhierarchical portions of the URI. The semicolon convention is used to identify matrix parameters:;w=39.001409,z=-84.578201;x=0,y=9 

These characters are valid in the path and query portions of URIs, but not all code libraries recognize the comma and semicolon as separators and may require custom coding to extract these parameters.

Full stop, or period

Apart from its use in domain names, the full stop (.), or period, is used to separate the document and file extension portions of the URI: 

The last example in the previous list is valid but might introduce confusion. Since some code libraries use the period to signal the start of the file extension portion of the URI path, URIs with multiple periods can return unexpected results or might cause a parsing error.

Except for legacy reasons, there is no reason to use this character in URIs. Clients should use the media type of the representation to learn how to process the representation. Sniffing the media type from extensions can lead to security vulnerabilities. For instance, various versions of Internet Explorer are prone to security vulnerabilities because of its implementation of media type sniffing (

Implementation-specific file extensions

Consider the following URIs: 

In all three cases, the data is the same and the representation format may be the same, but the file extension indicates the technology used to generate the resource representation. These URIs will need to change if the technology used needs to change.

Spaces and capital letters

Spaces are valid URI characters, and according to RFC 3986, the space character should be percent-encoded to %20. However, the application/x-www-form-urlencoded media type (used by HTML form elements) encodes the space character as the plus sign (+). Consider the following HTML:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html lang="en">
    <form method="GET" action=""
      <label for="phrase">Enter a search phrase</label>
      <input type="text" name="phrase" value=""/>
      <input type="submit" value="Search"/>

When a user submits the search phrase “Hadron Supercollider,” the resulting URI (using application/x-www-form-urlencoded rules) would be as follows: 

Code that is not aware of how the URI was generated will interpret the URI using RFC 3986 and treat the value of the search phrase as “Hadron+Supercollider.”

This inconsistency can cause encoding errors for web services that are not prepared to accept URIs encoded using the application/x-www-form-urlencoded media type. This is not just a problem with common web browsers. Some code libraries also apply these rules inconsistently.

Capital letters in URIs may also cause problems. RFC 3986 defines URIs as case sensitive except for the scheme and host parts. For example, although and HTTP://WWW.EXAMPLE.ORG/my-folder/doc.txt are the same, but isn’t. However, Windows-based web servers treat these URIs as the same when the resource is served from the filesystem. This case insensitivity does not apply to characters in the query portion. For these reasons, avoid using uppercase characters in URIs.

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