robert hahn

a darn good web developer

April 06, 2007

The 3 Rules of URI Design

There seems to be a problem that hasn’t been properly solved in aesthetic URI design. The problem is: How do I construct a RESTful set of URIs such that one GET request results in a read-only view of the data, and another GET request results in an editable view of the data? A key constraint on the solution: it must not rely on CSS or JavaScript, because we want the basic functionality to be available to all browsers.

Dave Thomas’ recent article on the RADAR architecture (well worth the read) is the impetus behind this article, and has crystallized some thoughts that I have about the matter. At the beginning of his article, he points to a problem: the Rails developers (or at least one of them, anyway) figured URIs of the type http://example.com/articles/1;edit was a perfectly reasonable way to request an editable representation of an article. Like Dave, I think it looks tacked on.

Joe Gregorio’s excellent series of articles discussing REST (here’s one) also has examples of URI fragments that I don’t much like, specifically /employees/1. Obviously, the pattern of plural noun followed by identifier is used by many others too.

At the core, this is simply a naming problem. RESTful URIs are nouns, because they name things. In the Rails URI example, we’ve got a verb tacked on. In Joe’s employee example, we have the notion of one thing being mashed with many things.

With that in mind, I wanted to see if there’s some kind of conceptual framework that can be employed for URI design. If I need to create a new, RESTful URI, what rules could I follow to ensure a consistent, predictable, simple design? Note that for the moment, I’m focusing entirely on representing a set of data within one mime type, in particular, HTML. Further, I’m focusing only on GETting a representation. If there’s call for it, I could try to see how this works with the other HTTP verbs.

Let’s start with some generalizations. For most things, (hence the generalization) we seem to look at pages that somehow fit the following criteria:

These statements can be organized into a quadrant graph:

Quadrant graph showing types of representations of data; consider the following combinations: read-only list; read-only item; editable list; editable item

The point of the graph is to illustrate what possibilities we could encounter when we’re surfing. If you look at any given page, they tend to fall into one of the 4 boxes. You can have a read-only representation of a list, or of a single item. You can also have an editable representation of a list or a single item. The surprise (to me) is the notion of an editable list of items, but there’s no technical reason why it can’t be done; most of the time applications are designed more to edit a single item at a time.

That said, I can’t think of a single resource that wouldn’t fit in any of the categories. Sure, sometimes you might only want to edit a particular attribute of an item, but the type of representation you’re dealing with is still an editable, single item.

Designing URIs for List-like representations

Let’s tackle URIs that would fetch a list of items. We would typically see URI fragments that look something like this:

That seems pretty straightforward; one would reasonably expect to see a list of employees or articles, and in RESTful apps, this is often the case. But what gets me are URI fragments that look like this:

The current convention is that those numbers somehow map to a particular article or a particular employee. While we’re used to the convention, it actually doesn’t make a whole lot of sense. I think that if you’re going to refer to /employees/, then anything past the trailing slash should also identify lists. /employees/marketing could refer to a list of employees in marketing. For references to a single employee, I would rather see this:

There’s no question that we’re referring to an employee with an id of 38, or a single article with an id of 5.

Rule #1: Use plural nouns to represent lists of things; use singular nouns to represent 1 particular thing.

Designing URIs for Different Views of the Same Data

Let’s consider the following set of URIs (I’m going to go ahead and apply rule #1 right now)

These URI fragments are readily understandable enough, and there’s obviously a lot going for the notion of human factors in URIs (strange, Google has nothing on URI Human Factors). But if you want RESTful URIs, then the verb edit has got to go.

It’s clear then that what I need to do is somehow qualify the noun in those URI fragments. /article/1 can be used to retrieve a default view of an article – likely a read-only view. If I want an editable view, I need to somehow modify the noun. Here are some approaches:

  1. /article/editable/1
  2. /editable/article/1
  3. /article/form/1
  4. /form/article/1

I’ve come up with two ways to qualify different views of an article: by adding an adjective (1 and 2), and by adding a noun (3 and 4). Either seems to work fine, and some URI fragments (2, 3) read more naturally than others.

Rule # 2: When creating alternate views of the same data, consider using compound nouns or an adjective-noun pair, depending on the problem space you’re working in. Whichever style you choose, stick with it for the entire site.

Scaling URIs for many views of the same data

Alright, if you’re willing to accept either style (because I can’t see that there’s anything to always prefer one over the other), then we should see how this applies to more complicated examples.

Consider a web application that’s used to manage information about international shipments. The amount of information that can be required to ship a package is absolutely astonishing, depending on what you want to ship where, so naturally, if someone wishes to change something in their shipment information, it would be good not to have them look at a huge page full of form fields.

If you are dealing with such a form, here’s how you might want to construct multiple editable views on the data:

It should be pretty easy to guess at what’s being asked for here – we use the /1 to qualify which shipment we want to view, then further qualify what it is about that shipment we want to inspect.

Rule #3: Given a complicated object with simple parts, design your URI so that you first qualify which complicated object you need a view on, then select which view you want on the simple part.

Combining the Rules

If you consider what I’ve covered in light of the quadrant graph above, I’ve defined some rules for addressing lists vs. single items, and read-only vs. editable views. Let’s look at how they could be combined. In getting this far, I’ve already combined the rules for some situations, so some of the example URI fragments already look familiar.

Illustration of URI fragments that leverage the 3 URI Design Rules
Type of view requested Sample URI Suggested interpretation
Read-Only; Single Item /article/1 View article ‘1’ Rule 1
Read-Only; List /articles/javascript View all javascript articles Rule 1
Editable; Single Item /article/form/1 View an editable version of article ‘1’ Rules 1, 2
Editable; List /articles/javascript/title/form/ View an editable list of titles for all javascript articles Rules 1, 2, 3

Conclusions

I wouldn’t be surprised if, upon looking at some of these examples, your first thought would be “is that it?” because many of the URI fragments don’t look at all that weird or new. And that’s as it should be. A lot of us who care about designing URIs are probably doing many of these things right without breaking a sweat.

And yet, we’re still left with conversations like you see in the comments of Dave Thomas’ RADAR article, and there are still a lot of people who are building websites with weird structuring conventions.

For your convenience, here are the 3 Rules of URI design in one place:

  1. Use plural nouns to represent lists of things; use singular nouns to represent 1 particular thing.
  2. When creating alternate views of the same data, consider using compound nouns or an adjective-noun pair, depending on the problem space you’re working in. Whichever style you choose, stick with it for the entire site.
  3. Given a complicated object with simple parts, design your URI so that you first qualify which complicated object you need a view on, then select which view you want on the simple part.

I’m interested in your comments. I’m not married to any of this; if you can convince me that there’s a better way of structuring the problem, or a better way of solving some of these issues, I’ll be happy to modify the document accordingly. I’d like this to become a resource that people who want to follow best practices.

decorative image of trees

Copyright © 2009
Robert Hahn.
All Rights Reserved unless otherwise indicated.