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:
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.
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.
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:
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.
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.
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.
|Type of view requested||Sample URI||Suggested interpretation|
|Read-Only; Single Item||
||View article ‘1’ Rule 1|
|Editable; Single Item||
||View an editable version of article ‘1’ Rules 1, 2|
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:
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.
Copyright © 2009
All Rights Reserved unless otherwise indicated.