Generally, you shouldn't expose too much to the user. A directory structure makes sense for some things, but not for everything. The typical var1-name/var1-value/var2-name/var2-value/
format is exposing variable names and can easily be avoided for most purposes.
Say you have a site which has a forum with threads that are paginated. You could make it use URLs like this: forum/<forum-id>/<thread-id>/<page-num>#post-<post-id>
. The only problem with this approach is that the directories can be ambiguous (e.g. how do you represent the above if the forum is paginated as well?).
StackOverflow follows the "fake human-readable" approach by giving you urls like questions/<question-id>/<pseudo-slug>
where the pseudo-slug
is actually not a unique identifier but can be any random string you want.
You can often provide sensible defaults for certain arguments to make the generated URLs shorter (and thus easier to remember). If you already do this, you should consider whether it actually makes sense to put the argument in a directory structure, i.e. does it actually affect what is displayed rather than just how it is displayed to the user? If it's the same content with different presentation, it may make more sense on a semantical level to just put the arguments in good old CGI variables and avoid distinct directory structures with essentially duplicated content (SEO guidelines often emphasize that you should avoid duplicated content -- Google's does, for example).
As for the "root" directory structure: /<controller>/<view>/
or even /<model>/<view>/
is a common default for some frameworks, but again it exposes internal structure. StackOverflow could use /questions/show/<question-id>/
, but that's more wordy and the "verb" (i.e. show
) is already implied by the HTTP method (GET
). I find that a structure like /<collection>/<item-id>/
is not only more RESTful, but also easier to remember.
If you want to add "methods" that do not fit into the traditional CRUD (e.g. specifying "properties" of that item to be shown in detail), you can easily extend that to /<collection>/<item-id>/<property>/
and if you have numeric IDs or don't mind special keywords, you can also add exceptions like /<collection>/<collection-attribute>/
where collection-attribute
can either be a property of the whole collection or an interaction method (I've seen conventions for RESTful structures where the special keyword new
via GET
is a form for creating a new item).
You can automate the process of exposing views via URLs, but while the URLs you create will be neat and consistent, they won't be pretty or easy to remember. Amazon doesn't seem to mind, but it's still a good idea to make URLs more recognisable and avoid the "mystery link" effect.