Mark Nottingham

URI Templating, the Spec

Wednesday, 4 October 2006

Internet and Web

As mentioned a while back, there are a variety of places where it would be useful to be able to describe the structure of a URI, rather than just convey a URI itself. I took a stab at this in the Link Header draft, and have also been working in the background with DeWitt Clinton, Joe Gregorio, Marc Hadley, Dave Orchard, and James Snell on a more general specification, URI Templates, the first draft of which we (finally!) got published today.

The idea behind URI templates is blindingly simple. There are lots of conventions that people use to denote the variable parts of URIs; one of them is to use {brackets}. All that we’ve done is codify that practice (brackets are a good choice because they’re not allowed in URIs, so there isn’t much risk of collision). For example,

http://www.example.com/users/{userid}/friends

Conceptually, a URI Template has a lot in common with forms (whether HTML or X), but they have a few advantages;

What benefit does this bring? Besides having a common convention for human-readable documentation (which IME is already pretty common), the real value is when templates are used by machines.

Marc Hadley’s WADL is a great example of this. Another is the Link-Template header, which allows you to build URI-centric protocols around link templates.

For example, lots of HTTP services will redirect you to an authentication URI, where you get a token in exchange for your credentials (the recently-released BBAuth is a good example of this). As part of that exchange, you need to communicate to the authentication server where to redirect the user after they successfully present credentials. E.g.,

http://www.example.com/signIn?onSuccess=http://other.example.org/i-want-to-go-here/

Right now, the way to do that is documented in prose. The problem is that there’s more than one authentication service out there, and each takes its arguments in a different form. Now, eventually we could come up with a general “third-party URI-based authentication” specification that everyone could implement, but the problem is that if such a beast existed, it would need to tell people how to form those URIs.

If the service you originally tried to use (you know, before you got redirected) returned a link template with the redirect;

HTTP/1.1 302 See Other
  Location: http://www.example.com/signIn?onSuccess=http://service.example.com/myService
  Link-Template: <http://www.example.com/signIn?onSuccess={success_uri}>; rel="login"

you’d have the best of both worlds; a user accessing myService directly would get authenticated and their browser would automatically follow Location to to back to where they started (but with the right credentials), and a third party (the BBAuth case) would be able to change the Location header they send downstream, based on the Link-Template, to send the person to the right place.

Similarly, you could use a URI-encoded template inside of success_uri to communicate to the authentication server where the login token should go.

Of course, there are a lot of caveats about this approach to authentication, but the important thing here is that URI-centric protocols like this can be constructed without stomping on URI opacity, if the right techniques are used. I have a feeling the same techniques could be very useful in APP, among other places.