Designing URIs
So this is a quick hack of a post I’ve been spending far too long failing to complete. Time to just get it out the door. If parts are nonsensical, please accept my apologies. You get what you pay for.
A fair bit has been written over the years about designing good URIs. Whilst traditional teaching on the subject must also apply to web applications to some extent, how far does it go? Does the nature of the documents being served (in this case ‘active’ documents as part of a larger application) hold sway over the URI of the page?
First Principals
I tend to be pretty fussy about what appears in the location bar of any sites or apps that I architect. Partly this is down to aesthetics and some idealist goal of elegance, but primarily it rests with the core values of sustainability, perception of stability and also ease of use. Let’s unpack that.
The subject of sustainability in URI design should be familiar to us all. At a base level, /contact
is good, but /contact.asp
is bad because when you transition your site to PHP next summer the name of that document is going to change. A good URI doesn’t refer to a web page with a document name. Unless the visitor is supposed to grab the file and take it away from the site, leave the file extension off.
Perceived Stability
Slightly more abstract than this is the concept of perceived stability, which I think is best illustrated with an example from last weekend. Dissatisfied with the tools available for discovering what podcasts are available, I was taking a look into writing my own scripts to parse the ipodder.org podcast directory and find stuff I might be interested in. The first job was to find the URI to the directory so that I could take a look at it. After some hunting around, I found this address:
http://www.ipodder.org/discuss/reader$4.opml
Well, ok it looks fairly compact, but I have a few issues with it. The first is that dollar sign. Are those even legal? Well, with the dollar being so weak it’s certainly not a good thing to be throwing into your URIs, that’s for sure. My second issue is the file name as a whole – whilst I’m not sweating the OPML extension as I know that to be XML, what’s with the reader business? And finally, discuss? That suggests that this was posted by a user and is not a permanent resource I should be building an application on. So with this bad taste in my mouth, I posted to a list and just asked if it was the right address. I was releaved to find that I had the wrong page. Phew! There I go getting hot under the collar for no reason. But wait until you see the real URI:
http://homepage.mac.com/dailysourcecode/DSC/ipodderDirectory.opml
Deeeep breath. So I have issues here too. The first is the dot mac account, which is obviously at the mercy of Apple and where they take their dot mac service in the future. The second issue is that the document I want (a directory of podcasts) is filled under the name of a specific podcast. It’s just all messed up. (And don’t even get me started on why the damn thing is in OPML format). See how the chosen URI can have a detrimental effect on the user’s perception of stability of that URI?
Ease of Use
So what would a better address for the ipodder.org directory be? Well, in the first instance, it should be on the ipodder.org domain. That’s where a user would expect to find the feed – it comes down to ease of use. Secondarily, the feed isn’t part of the mail content of ipodder.org, so I’d expect it be to tucked away in a directory distinct from the rest of the site’s content. How about this:
http://ipodder.org/xml/directory.opml
Short and too the point. Memorable, and most of all, easy.
Where was I?
Oh yes, so that’s how URI design works at a basic level. The challenge that I’m currently faced with is deciding if the principals of the design can or should be fundamentally different for a web application vs a regular site. I’ll tell you what’s prompted this thought – working with Rails. Rails uses a URI model that goes pretty much like this:
/controller/method/options
Well, I guess that’s pretty neat. A controller in use is often mapped to something like an object within your app – say, a user. So we have a controller for users. The address to edit user #1234 would be something like:
/users/edit/1234
That makes a lot of sense. What it’s doing is taking a object oriented look at the address structure rather than a traditional hierarchical view. The URIs reflect the logical structure of the application, not the hierarchical flow of the user interface. A subtle shift, and one that may have zero effect, depending on how your interface is designed.
On that note, I just checked some of mine. Here’s how I edit user #1234 in one of my recent apps:
/admin/users/edit/?id=1234
So that would be pretty much the same then. I’m going to have to think further about whether that means that my interface is well laid out, or whether it means that there’s little fundamental difference between app-logic designed URIs and UI-hierarchy designed URIs. I dunno. Discuss.