Re: URI Templates - optional variables?

Another syntax supporting optional variables… that aims to be much less cryptic in most cases. Many cases can have “normal” URLs with {} being the only extra characters.

{foo}
{/foo}
{&foo=} and {?foo=}
{&bar=foo} and {?bar=foo}
{!foo}
{;foo}
{,foo}
{<any of the above>|default}

http://example.net/{yyyy}{/mm}/{title}?id={id}{&page=}
-> http://example.net/2007/Cat?id=b7
-> http://example.net/2007/03/Dog?id=&page=2

The whole {…} expression is omitted if the foo variable is undefined or an empty string (or it is replaced by the default if provided). That way the whole path segment including the leading /, or the whole query parameter can be omitted resulting in “clean” URLs.
{&bar=foo} is an optional query parameter. {&foo=} is a shorthand equivalent of {&foo=foo} for the (probably quite common) case where the query field name and variable name match. Nothing is added to the URL if foo is undefined or an empty string.
{?bar=foo} and {?foo=} are identical to {&bar=foo} and {&foo=}. Both versions are included so templates look more like URLs for authors. In both cases the replacement text must start with ? if it is the first query parameter in the resultant URL and & otherwise.

All non-unreserved characters in variable values are %-escaped, except when the template is {!foo}. For {!foo} only characters that are illegal in URLs are %-escaped. In particular, reserved characters are NOT escaped when replacing {!foo}. This allows {!foo} to be used whenever the URLs are too complex for the other rules. It does not allow complex restrictions on the resultant URLs, but at least almost any URL can be created.

Variable name MUST start with an unreserved character (or i18n alpha-numeric char?). Variable names must not contain | } =

Examples:
http://bitworking.org/news{/num}/{entry}
when entry=RESTLog_Spec -> http://bitworking.org/news/RESTLog_Spec
when num=240, entry=Newsqueak -> http://bitworking.org/news/240/Newsqueak

http://technorati.com/search/{term}
when term=“240/Newsqueak” -> http://technorati.com/search/240%2FNewsqueak

http://example.net/draw{?a=}{&b=}{&c=}{&d=}
when a,b,c & x are absent -> http://example.net/draw
when b=5, d=2 -> http://example.net/draw?b=5&d=2

http://google.com/-/{!category}
when category=fred -> http://google.com/-/fred
when you want (A OR (NOT B)) AND (NOT C) then category=“A|-B/-C” -> http://google.com/-/A%7C-B/-C


Security considerations: (for this syntax, or almost any other)
A replacement MUST not affect parts of the URL template before or after the {}. We have to be careful of “..” and “.” path elements (even if the dots are %-escaped if unescaping unreserved chars is allowed almost anywhere).
When expanding a {!foo} template the variable value:
- MUST NOT have an (unescaped) % as the last or 2nd last character;
  foo=“abc%” is illegal, foo=“abc%25” is allowed
  foo=“abc%3” is illegal
- MAY have “.” and “..” path segments but they MUST NOT cause any of the URL before the {} to disappear after relative resolution (RFC 3986 §5.2) is performed.
[Need some more words for cases where {!foo} is not the last item in the template. For instance, http://example.net/{!foo}?x=2 -- consider foo=“a?y=1”. Do we want this to become http://example.net/a?y=1?x=2 (1 query param y with a 5-char value); or http://example.net/a?y=1&x=2 (preserving query params in the value and template separately).]

Default:
A default value {<any rule>|default} replaces the {} expression if the variable is absent or an empty string. The default is NOT escaped. It is not subject to “.” or “..” restrictions. It MAY affect other parts of the URL. Because it is part of the template, not the values being inserted into the template, no restrictions are necessary. Weird defaults can cause weird URLs, but that is the template author’s fault.
http://example.net/news/{entry|../latest}
when entry=“dogs” -> http://example.net/news/dogs
when entry is absent -> http://example.net/news/../latest -> http://example.net/latest


Extensions:
{*<any of the above}  - The template can repeated 0, 1 or more times.
{+<any of the above}  - The template can repeated 1 or more times.

Probably useful to have a special rule that for /{*;foo} or /{*,foo} the first ; or , is omitted if the character immediately before the {} is /.

James Manger

Received on Monday, 22 October 2007 15:17:18 UTC