Sound advice - blog

Tales from the homeworld

My current feeds

Sun, 2005-May-08

Gnome 2.10 Sticky Notes

According to the Gnome 2.10 "what's new":

sticky notes now stay on top other windows, so you can't lose them. To hide the notes, simply use the applet's right-click menu.

So now sticky notes have two modes:

  1. In my way, or
  2. Out of sight, out of mind

I do not consider this a feature. If you are using sticky notes with Gnome 2.8 or earlier, I do not recommend upgrading!

Update: I've placed a comment on the existing bug in Gnome bugzilla.

Benjamin

Sun, 2005-May-08

Describing REST Web Services

There has been some activity lately on trying to describe REST web services. I don't mean explain, people seem to be getting the REST message... but to describe them so that software can understand how to use them. I saw this piece during early april. The idea is to replace the SOAP-centric WSDL with a REST-centric language. Essentially it describes how to take a number of parameters and construct a URI from them. Here is their example:

<bookmark-service xmlns="http://example.com/documentation/service">
	<recent>https://example.com/{user}/bookmarks/"</recent>
	<all>https://example.com/{user}/bookmarks/all"</all>
	<by-tag>https://example.com/{user}/bookmarks/tags/{tag}/"</by-tag>
	<by-date>https://example.com/{user}/bookmarks/date/{Y}/{M}/"</by-date>
	<tags>https://example.com/{user}/config/"</tags>
</bookmark-service>

Frankly, I don't agree. I've had some time to think about this, and I am now prepared to call it "damn foolish". This is not the way URIs are supposed to be handled. Note the by-date URI, which has an infinite number of possible combinations (of which some finite number will be legal, for the pedants). Look at the implicit knowledge required of which user parameters and which tag parameters are legal to use. It's rubbish.

There are two things you need to do to make things right. First off, there is a part of the URI which is intended to be constructed by the user agent rather than the server. This part is unremarkably called the query part, and exists after any question mark and before any fragment part of a URI reference. I consider this part to be the only appropriate space for creating URIs that are subject to possibly infinite variation. The {Y} (year) and {M} (month) parameters must follow a question-mark, as must {tag}.

The second thing you need to do is use RDF to describe the remaining (finite) set of URIs. Somewhere at the top of the URI path hierarchy you create a resource that lists or allows query over the set of users. If that's not appropriate, you give your user an explicit URI to their representation in the URI space. I, for example, might reside at "https://example.com/fuzzyBSc". At that location you place a resource that explains the rest of the hierarchy, namely:

<bookmark-service
	xmlns="http://example.com/documentation/service"
	rdf:about="https://example.com/fuzzyBSc"
	>
	<recent rdf:resource="https://example.com/fuzzyBSc/bookmarks/"/>
	<all rdf:resource="https://example.com/fuzzyBSc/bookmarks/all"/>
	<by-tag rdf:resource="https://example.com/fuzzyBSc/bookmarks/tags/"/>
	<by-date rdf:resource="https://example.com/fuzzyBSc/bookmarks/date/"/>
	<tags rdf:resource="https://example.com/fuzzyBSc/config/"/>
</bookmark-service>

Separately, and tied to the rdf vocabulary at "https://example.com/documentation/service" you describe how to construct queries for the by-tag and by-date resources. I don't even mind if you use the braces notation to do that (although clearly more information than just the name this method provides will be required, for example a date type wouldn't go astray!):

<URIQueryConstruction>
	<!-- tag={tag} -->
	<Param name="tag" type="xsd:string">
</URIQueryConstruction>
<URIQueryConstruction>
	<!-- Y={Y}&M={M} -->
	<Param name="Y" type="xsd:integer">
	<Param name="M" type="xsd:integer">
</URIQueryConstruction>

Alternately, you make https://example.com/fuzzyBSc/bookmarks/tags/ contain a resource that represents all possible sub-URIs. Again, this would be a simple RDF model presumably encoded as an RDF/XML document. Another alternative again would be to incorporate the tags model into the model at "https://example.com/fuzzyBSc/".

So I know that https://example.com/fuzzyBSc/bookmarks/tags/?tag=shopping (or https://example.com/fuzzyBSc/bookmarks/tags/shopping at the implementor's discretion) will lead me to shopping-related bookmarks owned by me, and that https://example.com/fuzzyBSc/bookmarks/date/?Y=2005&M=05 will fetch me this month's bookmarks.

Personally, I think that some REST proponents are confusing (finite) regular URI and (infinite) query URI spaces too much. There are important distinctions between them, particularly that you can deal with finite spaces without needing client applications to construct URIs using implicit knowledge that might be compiled into a program based on an old service description or explicit knowledge gleaned from the site.

The RDF approach (when available) allows sites to vary the construction of these finite URIs from each other so long as they maintain the same RDF vocabularies to explain to clients which resources serve their specific purposes. The substitution approach must always follow the same construciton or a superset of a common construction. This is probably not so important for a very specific case like this bookmark service, but may be important for topics of wider interest such as "how do I find the best air fare deal?". Using the RDF approach allows you to navigate using a very general scheme with few constraints on URI construction to sites that require detailed knowledge to be shared between client and server to complete an operation.

Update: A link summarising various current attempts

Benjamin