URI Templating, the Spec
Wednesday, 4 October 2006
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;
- They’re strings, not full markup. You can use a template anywhere you need a short way to say how to construct a URI, like in an XML attribute, or an HTTP header.
- You can put variables anywhere in the URI, not just the query string, allowing well-modelled resources to be constructed.
- It’s easy to construct and evaluate them. Since brackets aren’t valid in normal URIs, they make great delimiters.
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.
Authentication with 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.
8 Comments
Jerome Louvel said:
Thursday, October 5 2006 at 1:02 AM
M. David Peterson said:
Friday, October 6 2006 at 4:07 AM
Nick Thompson said:
Sunday, October 15 2006 at 1:28 AM
pwb said:
Monday, October 16 2006 at 8:37 AM
Mark Nottingham said:
Monday, October 16 2006 at 10:26 AM
Mark Nottingham said:
Thursday, October 19 2006 at 8:18 AM
pwb said:
Thursday, October 19 2006 at 12:11 PM
Marc Brooks said:
Friday, June 22 2007 at 10:38 AM