Monday, December 3, 2012

Navigation and Object URIs

How do we go about designing a web application that does well with both the navigational structure presented to the user, and the URI format used to traverse the application? They really are distinct problems, are they not? If so, I find that I've artificially blended the two concepts together. Maybe that's because, as a user, I've unintentionally joined the two ideas. After all, they both play a role in the same job. They take the user from one place to another. One from presents a graphical layout to the user, often with styled elements using some kind of grid layout. The other, is just a string destined for the browser address bar. An action in the navigational menu often means a change in the URI. The change is triggered from the user interface, and I would think that this is the expected pattern of behavior, as opposed to the user constantly typing in the desired location — unless the menu is really that bad.

From a software development point of view, what is it exactly, that we have to gain by treating the URI and the graphical navigation depiction as distinct problems? Thinking about the relationship between what the user understands as navigation in the UI versus what they understand as navigation in the URI address bar reveals some important user traits. Consider your own browsing habits, in particular, think about moving around in one web application as opposed to bouncing from site to site. How do you do it? Is it different from how you did it ten years ago? And so on. When I think about these things myself, I think how little I care about the address of the resource I'm looking at. The strange thing is, I especially don't care for long URIs — as I'm sure most don't — but I actually notice the smaller ones. The ones that have at most two forward slashes in them. They're beautiful. I can almost remember them. But the key point is that I don't have to. The navigation that I can see and interact with and click my mouse on — that's how I got to where I am. I'm looking at something specific, and this is reflected by the URI, usually with some sort of object identifier — depending on how the resource is represented in whichever back-end storage system happens to be deployed for the application.

Nice URIs, and a detached navigational system — pretty'd up for my own enjoyment. Again, looking at this from the development point of view, why would we want to take existing software components through such a drastic change? There are lots of web application frameworks out there, for whatever language you choose, all of which have navigational components in one form or another. If you want to employ one of these as the solution inside your given application, you've just saved yourself a ton of work. And I wouldn't want to reinvent application components either. Especially something so fundamental as navigation. Especially when the component probably stores the state of the navigation — where the user currently is — inside the URI path. The very thing we want to avoid is unavoidable, I'm afraid, with many such navigational components today.

At one point, if you develop software for the web and that software relies on storing application-level navigation paths in the URI, take a look at something that has a small, readable structure. Think about GitHubowner/repository. Think about the Django admin UI where you have an object type, and it's primary key identifier. These structures aim for the most readable form possible, providing only the absolutely necessary context. For example, the Django admin user interface might look something like — app/model/id. The extra application context in the path doesn't dictate how, in the user interface, we create and display menus. Navigational URIs, like /bargains, should have no real bearing on the object. For example, while bargains would introduce the new /bargains URI, probably used in a navigation menu on the home page, we wouldn't want /bargains/books/thrillers/38472. Just because the book is a bargain doesn't mean we need to take away from it's URI value — it can still be /books/38472 and still convey the same bargain information.

At the end of the day, it would be nice if we as developers could completely encapsulate URIs be removing the address bar so we'd be free to use whatever convention we're comfortable with. Given that that ain't gonna happen, let's take the user's behavior into consideration. It's easier to switch software systems than it is to listen to software developer's rationale. Let's respect the URI and try our best to use user interface navigation in such a way that values simple, readable, URIs.