08:24 PM, Wednesday, April 09, 2008

Opacity of URIs

When it comes to URI design, I am in the camp that argues that URIs ought to be opaque as far as the representations are concerned. In my view, URIs and representations are two independent axes of web service design, and must be designed to be evolved independently of each other, and that URIs should not be used to infer the structure of representations. Does this mean that URIs should be completely opaque and cryptic, like the following ...

http://accessories.us.dell.com/sna/products/Windows_Mobile_PDAs/productdetail.aspx?c=us&l=en&s=biz&cs=555&sku=A1153537

No. It should be possible to guess or interpret the nature of the resource by looking at a URI. That is, URIs are opaque to a machine dealing with the web service (unless otherwise described through a specification of the URI), but transparent to the user, like the following:

http://www.cnn.com/2008/POLITICS/04/09/clinton.iraq/index.html

An old W3C note on The use of metadata in URIs, describes the principles very well.

A related issue is resources carrying references to other resources. Consider, for example, my profile on a social networking site referring to pool of pictures uploaded by me? One common pattern is the following:

<photos page="2" pages="89" perpage="10" total="881">
  <photo id="2636" owner="47058503995@N01" 
    secret="a123456" server="2" title="test_04"
    ispublic="1" isfriend="0" isfamily="0" />
  <photo id="2635" owner="47058503995@N01"
    secret="b123456" server="2" title="test_03"
    ispublic="0" isfriend="1" isfamily="1" />
  <photo id="2633" owner="47058503995@N01"
    secret="c123456" server="2" title="test_01"
    ispublic="1" isfriend="0" isfamily="0" />
  <photo id="2610" owner="12037949754@N01"
    secret="d123456" server="2" title="00_tall"
    ispublic="1" isfriend="0" isfamily="0" />
</photos>

This is used by Flickr's photos.getRecent API. In this model, the photos element is a collection of photo elements each referred to by two IDs, viz, an ID for the owner, and another ID for the photo.

To GET each of photo from this collection, the client will have to refer to another part of Flickr API documentation to learn how to construct a URI.

This is an exception to the opacity rule. Here the web service specified how to construct URIs, and so a machine client could construct URIs programmatically.

Still, this is no match for the following:

<photos page="2" pages="89" perpage="10" total="881">
  <photo uri="http://farm2.static.flickr.com/2/2636_a123456.jpg"     
    owner="http://www.flickr.com/photos/name1"
    title="test_04" ispublic="1" isfriend="0" isfamily="0" />
  <photo uri="http://farm2.static.flickr.com/2/2635_b123456.jpg"      
    owner="http://www.flickr.com/photos/name1"
    title="test_03" ispublic="0" isfriend="1" isfamily="0" />
  <photo uri="http://farm2.static.flickr.com/2/2636_c123456.jpg"        
    owner="http://www.flickr.com/photos/name1" 
    title="test_01" ispublic="1" isfriend="0" isfamily="0" />
  <photo uri="http://farm2.static.flickr.com/2/2636_d123456.jpg"         
    owner="http://www.flickr.com/photos/name1"
    title="00_tall" ispublic="1" isfriend="0" isfamily="0" />
</photos>

where the URI is explicitly provided as part of the representation so that a machine client would immediately know to fetch the resource without manufacturing URIs. If a web service is providing IDs to resources only to let the client be able to construct a URI, it is better to provide the URI in stead of IDs.

How about URI Templates? URI templates serve a useful purpose by letting opaque URIs be programmable. But they should not be used to avoid serving URIs, as above.

Comments

Good start. What about using standard formats?

<feed xmlns="http://www.w3.org/2005/Atom">
    <title type="html">Photos</title>
    <id>http://flickr.com/users/bob/photos</id>
    <updated>2008-04-02T08:55:48+10:00</updated>
    <author>
        <name>Joe Blo</name>
        <uri>http://www.flickr.com/photos/name1</uri>
    <author> 
    <link rel="previous" href="http://flickr.com/users/bob/photos/pg1">
    <entry>
        <title>test_04</title>
        <flickr:is_public>True</flickr:is_public>
        <flickr:is_friend>False</flickr:is_friend>
        <flickr:is_family>False</flickr:is_family>
        <link rel="alternate" type="image/jpg" href="http://farm2.static.flickr.com/2/2636_a123456.jpg" />
        <id>http://farm2.static.flickr.com/2/2636_a123456.jpg</id>    
        <published>2008-04-02T08:55:48+10:00</published>
        <updated>2008-04-02T08:55:48+10:00</updated>
    </entry>
</feed>

Give in to the power of the Atom, Subbu...

Thanks Mark. Of course, that is much better.

Leave a comment