.aspx considered harmful

It’s been a decade since Tim Berners-Lee wrote Hypertext Style: Cool URIs don’t change, the first contribution to what is still not a very extensive literature on designing namespaces for the web. Recently, when I made the suggestion that a blog engine ought not produce URLs that end with .aspx, I was asked: “Why does it matter?” For me it boils down to two reasons:

  1. Futureproofing
    A blog posting is, in theory, a permanent artifact. You’d like its URL to remain constant. Sometimes, of course, change is unavoidable. URLs aren’t digital object identifiers, and for most web resources, there’s no way to insulate yourself from an ownership change that results in a domain name change. But you don’t want to subject yourself to avoidable change, and file extensions fall into that category. Last year foo.asp, this year foo.aspx, next year something else, the only meaningful part of the name is foo. The technology that produces the name, never mind the version of that technology, is a variable that need not, and should not, be exposed. If links are pointing to foo.asp, and your upgraded blog engine produces foo.aspx, you broke those links. That’s unnecessary and avoidable.

  2. Style
    Names without extensions are cleaner and simpler. Why does that matter? I guess if you think of URLs as constructs generated by machines for machines, then it doesn’t, because machines don’t care about style. But I believe that even when they’re machine-generated, URLs are for people too. We read, cite, and exchange them. Their structure and content conveys meaning in ways that warrant thoughtful analysis. Elements that don’t convey meaning, and that detract from clarity, should be omitted.

The Strunk and White Elements of Style for the literary form that is the web’s namespace hasn’t really been written yet, but Tim Berners-Lee’s 1998 essay belongs in that genre. So does the Richardson and Ruby book RESTful Web Services which, as I noted in my review, recommends that URIs use forward slashes to encode hierarchy (/parent/child), commas to encode ordered siblings (/parent/child1,child2), and semicolons to encode unordered siblings (/parent/red;green). We can, and we should, think and act in principled ways about the web namespaces we create.

I guess I’m extra-sensitive to the .aspx thing now that I work for Microsoft, because I know that to folks outside the Microsoft ecosystem it screams: We don’t get the web. It’s true there are plenty of .php and other extensions floating around on the web. But non-Microsoft-powered sites are far more likely to suppress them than are Microsoft-powered sites, because you have to go out of your way to get IIS and ASP.NET to do that.

Happily, that’s changing. The URL rewriting capability that’s long been standard in Apache, and is integral to modern web frameworks like Rails and Django, is coming to ASP.NET. From Scott Guthrie’s introduction to the ASP.NET MVC Framework:

It includes a very powerful URL mapping component that enables you to build applications with clean URLs. URLs do not need to have extensions within them, and are designed to easily support SEO and REST-friendly naming patterns. For example, I could easily map the /products/edit/4 URL to the “Edit” action of the ProductsController class in my project above, or map the /Blogs/scottgu/10-10-2007/SomeTopic/ URL to a “DisplayPost” action of a BlogEngineController class.

I hope that cool URIs will become the default for Microsoft-powered websites and services. Meanwhile, there are a variety of add-on URL rewriters for IIS that can streamline and normalize web namespaces. I wish they were used more extensively.

27 thoughts on “.aspx considered harmful

  1. Mark Holder

    Is the work of the library sciences community being extended to the web? Scaling would be one of many issues, but a lot of efficiency could be gained if web based data sources were classified according to the same principles libraries use.

    It would be nice to have an “internet card catalog” rather than relying on search engines to find everything.

    http://en.wikipedia.org/wiki/Library_classification

    Reply
  2. Michael R. Bernstein

    it’s worth noting that Zope pioneered human readable URLs in a web application framework as far back as 1998 (at the time, it was also much more search-engine friendly, too). Slash-based hierarchical object traversal has been a core concept in Zope from the very beginning.

    Reply
  3. Chris

    Absolutely. URLs are brands, permanently on display for every webpage. The user wants to know what the page is about, not what technology you’ve used to put it together.

    Incidentally, with OpenID, our login IDs will become URLs too. It’ll be interesting to see what patterns emerge for their use! I’ve seen a few of the form {blogURL}#me already.

    Reply
  4. Peter Murray

    On a related note, it would also be nice if a web server suppressed (through a 301 Moved Permanently status code) whatever the default document is for a point in the directory hierarchy — be it “index.html” or “index.htm” or “Default.htm” or “index.php” or whatever.

    Reply
  5. Gumnos

    Extensions aren’t bad of their own right. However they should be used to reflect the *content* type, not the *production method*. Thus, /path/to/file.html points to an HTML file, /path/to/file.txt points to a plain-text file, and other extensions such as .json, .xml, .rss, .xslt, .pdf, .gif, .jpg, .png, .svg, .pdf, .ps, or even .xls, .doc, .odt, and .ical are all fine. If I see a file of the form http://example.com/path/to/file.rss I expect the result to be an RSS feed.

    The generating method should never be exposed (your .php, .asp, .aspx, .pl, .py, .cgi, .java, etc) in the URL. There’s no way to know what’s there without doing a HEAD/GET request to sniff the content-type header.

    The better web-development frameworks (I prefer Django, but Rails for some, Turbo Gears/CherryPy/Pylons for others, etc) make it very easy to make clean URLs. Other frameworks such as ASP and PHP tend to make the developer jump through hoops just to get clean URLs.

    -Tim Chase

    Reply
  6. Sean Upton

    MVC is not a one-to-one function for a URI.

    Okay, so mapping is nice. This MVC thing is nice, but it is still software-centric, not content-centric in its representation of the universe. The “resource” in Universal Resource Identifier is, for these mapping systems, the controller (C in MVC), not the content.

    What Zope does with traversal is much more novel than what the MVC mapping systems do. Martin Aspeli elaborates (better than I can) on this here: http://martinaspeli.net/articles/screw-the-pattern

    If you have a large content space, it will be flattened by mapping-based MVC systems that are software-centric (not content-centric). I suppose this is the natural tendency of most developers, but in systems where the path hierarchy should be maintained by content people, not IT people (like web content management), this pattern has an issue of scale.

    Reply
  7. Jon Udell Post author

    “However they should be used to reflect the *content* type, not the *production method*.”

    Of course there are other ways to do that, e.g.:

    http://del.icio.us/rss/judell/servicemanagement

    The discussion of content type and negotiation in Tim BL’s essay is actually quite interesting:

    “References which do have the extension on will still work but will not allow your server to select the best of currently available and future formats.

    (In fact, mydog, mydog.png and mydog.gif are each valid web resources. mydog is content-type-generic. mydog.png and mydog.gif are content-type-specific.)”

    This notion of being “content-type-generic” has some subtle but, to me, important implications. Consider a scientific paper that’s published, as many are, in .HTML and .PDF. If names were generic and content negotiation worked like it could, you’d get a canonical URL that would consolidate references to any of the types. Bookmarks, blog items, and other references would cluster together much better than they can when they have to hardcode differing type extensions. Connectivity and coherence would improve.

    Reply
  8. Jon Udell Post author

    “in systems where the path hierarchy should be maintained by content people, not IT people”

    That’s a great point. Sometimes it’s appropriate for developers to design the namespace, sometimes users. In both cases the infrastructure should cooperate, not get in the way. I guess what you’re saying is that the appropriate kind of cooperation between the infrastructure and developers or users will vary according to who’s involved. If so, I agree.

    Reply
  9. Sean Upton

    Thinking about this a bit more: on systems that do mapping of URLs (e.g. Django, Pylons, etc), the mapping itself is just an entry point. If you had a big-content system with a large dynamic hierarchy, you would likely code up a “view” or “controller” that acts much like the Zope publisher does, traversing the remainder of the path from left-to-right in content space. Somewhere one of those slashes in the path is the demarcation point between IT control and content/knowledge-worker control.

    So mapping is certainly a good start… and here’s to hoping that my Microsoft-bound mortgage servicer can eventually give me PDFs of my statements that I do not have to rename from .asp to .pdf in Finder every time I download them (to get Preview on my Mac to open them).

    Reply
  10. Bill Thorp

    ‘It would be nice to have an “internet card catalog” rather than relying on search engines to find everything.’

    I am entirely pleased that I cannot tell whether this is a joke or not.

    Reply
  11. Gumnos

    [quote]

    “reflect the *content* type, not the *production method*.”
    Of course there are other ways to do that, e.g.:

    http://del.icio.us/rss/judell/servicemanagement

    [/quote]

    I just re-read through your three articles linked from there, and (assuming you gave the right link) I’m not sure I follow how the articles apply to the matter of file extensions being used to convey the file-type.

    [quote src="Tim BL essay]
    Consider a scientific paper that published, as many are, in .HTML and .PDF. If names were generic and content negotiation worked like it could, you get a canonical URL that would consolidate references to any of the types. Bookmarks, blog items, and other references would cluster together much better than they can when they have to hardcode differing type extensions. Connectivity and coherence would improve.
    [/quote]

    By offering extensions, you avail the option to refer to an object both in the generic and in the specific. If I provide a link to http://example.com/item you (or your programatic proxy) need to negociate on the terms. My GET request comes in, how does your server return a representation of that object? Either your server needs to make an assumption about my desires, or it needs to indicate that there are multiple possibilities for representing this object. HTTP does provide the “300 Multiple Choices” response code (http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.3.1 for the gritty details). My end then needs to decide which representation it wants and then round-trip a second request to a distinguished entity…say one with an extension. So for a particular representation of an object, you need to convey that, and extensions make an ideal and well recognized way of doing that. It logically follows that something without an extension (a representation of an entity) is a generic. I would proffer that any URL without an extension should *always* return a 300 response code because
    1) it’s the right thing to do and
    2) since the user hasn’t specified the format, you shouldn’t guess. The 300 code allows for a “Location:” header to offer a suggested location.

    Unfortunately, the W3 specification doesn’t define the format for offering multiple file-types in a 300 response, but only specifies that the Content-Type header should be used to encode the format the list of representations are shown in. This vacuum leaves us back where we started…plain-text? XML (and with what schema)? JSON? HTML? XHTML?

    Anyways, Django (and likely other high-quality frameworks) makes this very easy to do as I can just sniff the extension and then send the resulting view’s context through a corresponding template if it exists. Or, if no extension exists, I can return a 300 with a Location: and Content-Type header to provide my suggested format (usually HTML) and a list of alternate formats (also usually in HTML, via a UL of links).

    Reply
  12. Jon Udell Post author

    “I would proffer that any URL without an extension should *always* return a 300 response code”

    Really interesting point. Clearly I hadn’t thought this through :-)

    From this point of view there’s just no point in try to make URLs more DOI-like. With a DOI, you wind up in the same place as you propose: You’re always going to get redirected.

    Reply
  13. roberthahn

    Gumnos makes a lot of great points about interpreting file extensions as content type. There’s still something else that should be taken into account: There is no web browser designed to let us choose which representation we want – instead, it sends a pre-formatted Accept: header with values biased for filetypes we historically were interested in (eg: HTML, then popular image formats).

    So the only way for people with browsers to request files of a certain type is to specify the file extension in the URI.

    Reply
  14. Gumnos (Tim Chase)

    [quote]
    From this point of view there’s just no point in try to make URLs more DOI-like. With a DOI, you wind up in the same place as you propose: You’re always going to get redirected.
    [/quote]

    So yes, DOI’s are helpful for referencing something in the generic, but to obtain a usable representation, you have to request it in the specific. For your example, that means http://example.com/judell/phd-thesis may be what I cite, but when I fetch it, do I want the PDF version? the HTML version? the plain-text version? or perhaps an XML version? Maybe I want your spoken variant, in which case do I want it in MP3, OGG, Flac, Speex, WAV, WMA, or any of a bajillion other formats. Perhaps I want a video of you reading your thesis and defending it so I can see your slides in the background, so I request the .MOV or .AVI version.

    The question then becomes “How does one standardize the representation of a 300 response so that it can be processed using a known vocabulary?”. There are an arbitrary number of facets to explore with a variety of metadata to attach, making XML (or YAML) a good candidate for representation of a 300′s content.

    Using the example of a PhD thesis, you may want to convey in your 300 response an arbitrary number of facets: Rendering integrity, data/meta-data integrity, quality, size, copyright licensing, etc. The possibilities are fairly limitless:

    ====================
    Rendering integrity: PDF or PS may be photo-exact and resolution independent; GIF/JPG/PNG may be photo-exact, but resolution dependent; HTML may be close in presentation and resolution independent; TXT may be a mere skeleton of the printed version.

    Data/meta-data integrity: rendering your thesis as GIF/JPG/PNG loses a lot of information; rendering as PDF/PS/TXT loses some information but the content may still be searchable; rendering as HTML keeps some of the structural information in addition to the content; and XML may offer the strongest structuring for representation of internal structure and meta-data.

    Quality (related to rendering integrity) and Size: rendering your thesis as MP3/OGG vs. FLAC vs. Speex, there’s a matter of audio quality vs. size. Speex works great for the spoken word, but if your thesis is about (and includes) music or performance

    Copyright licensing: you may license the textual variants under a liberal CC license, while licensing the audio or video variants under a stricter license.

    ====================

    Yet you can still put a default format in your Location header to transparently redirect a browser to, say, the preferred PDF or HTML version.

    Just a few more thoughts on generic vs. specific content, and ill-defined 300 response content… :)

    -Tim Chase

    Reply
  15. Jon Udell Post author

    “The question then becomes “How does one standardize the representation of a 300 response so that it can be processed using a known vocabulary?”.”

    That’s a really good question!

    “There is no web browser designed to let us choose which representation we want”

    Right. We send Accept as you say, but we don’t send Prefer, even though I almost always prefer, say, HTML (if available) to PDF.

    Reply
  16. Gumnos (Tim Chase)

    [quote]
    Right. We send Accept as you say, but we don’t send Prefer, even though I almost always prefer, say, HTML (if available) to PDF.
    [/quote]

    Preference also requires a context. We may “almost always prefer HTML”, but I’d rather http://example.com/styx/come-sail-away come back as MP3 or OGG than as HTML or PDF. And heaven help us if it came back as XLS…

    You yourself wrote about contextual problems:

    http://jonudell.net/bytecols/2001-05-30.html

    only at the time, you were addressing file-systems, not the web. But in a way the web is just a glorified file-system, so I’d say it still holds, and you can claim prognostication bragging rights. :)

    [quote]
    “The question then becomes ‘How does one standardize the representation of a 300 response so that it can be processed using a known vocabulary?’”

    That’s a really good question!
    [/quote]

    My answer: Skip the generic. It becomes a mostly useless (read “underdefined) way of redirecting to alternate formats. Instead, just reference a particular (such as http://jonudell.net/phd-thesis.html ) and then within that (a known ontology), link to other formats. This is done all the time with HTML links. The MP3 version of your thesis may have you speaking the reference “This presentation of my thesis is available online at http://jonudell.net/phd-thesis.pdf and the slides are available at http://jonudell.net/phd-thesis.ppt“. The PDF version may have a link to http://jonudell.net/phd-thesis.avi for the video of your presentation.

    -Tim

    Reply
  17. Pingback: Max Design - standards based web design, development and training » Some links for light reading (22/1/08)

  18. Richard Morton

    I don’t think that the extension is that important, providing it doesn’t have query strings etc. It is a slight distraction, and can make life more difficult if taking a URL over the phone, or trying to remember a URL and having to use some guesswork for the extension.

    I can see the elegance of URLs like http://example.com/item but the disadvantage to my mind is that it doesn’t pass the Steve Krug “Don’t make me think” test. In other words if I am typing in a URL like that it is probably 50/50 that I might assume that item is the name of a folder and thus type http://example.com/item/

    Reply
  19. Jon Udell Post author

    “You yourself wrote about contextual problems:
    http://jonudell.net/bytecols/2001-05-30.html

    Wow. :-)

    “Skip the generic.”

    Hmm. Today’s entry suggests one way that can work.

    http://blog.jonudell.net/2008/01/22/bloggers-talk-to-bloggers-scientists-talk-to-scientists/

    Whether or not bloggers cite generic DOIs or PubMed URLs, those forms could be discovered by the citation engines and used to thread conversation together much better than happens now.

    Reply
  20. Frederick Townes

    A bit of an aside, though relevant in one regard. I feel that open standards for presentation (CSS) and markup (HTML) still need more standarization and popularity for that matter. Once the above are coupled with complete functionalality seperation, the extension of documents would certainly be less relevant. I think what I describe is exactly what was intended rather than diversification of document types of which only the web server itself needs to be aware.

    Reply
  21. Pingback: Doc Searls: It’s too hard to find and share the coolness of Live Maps « Jon Udell

  22. Pingback: Attempting some permalink magic | Dave Bost

  23. Stu Smith

    If anyone’s interested, I have code that lets you do this easily in “standard” ASP.NET (i.e. no MVC needed). It supports postbacks nicely too, and allows remapping to parameters, for example:

    Foo/*/Edit -> Foo/Edit.aspx?f={0}

    I’ve been thinking for a while about packaging it all up (for example, I also have code that lets you use UserControls from separate assemblies in ASP.NET, something that isn’t supported ‘out of the box’), so if anyone fancies testing it in return for essentially a free licence, drop me an email (stu ‘at’ feedghost ‘dot’ com).

    Reply
  24. Pingback: andyskipper.com - freelance web developer in london

  25. Pingback: J. Boye » Blog Archive » Smart practitioners have harmless URLs

  26. Pingback: Redirecting Routes To Maintain Persistent URLs | josue59carrillo

  27. Pingback: Redirecting Routes To Maintain Persistent URLs | mathew53santos

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s