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 a whole path segment including the leading /, or the whole query parameter can be omitted resulting in “clean” URLs. // path segments can be avoided.
{&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 names 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 & d 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 a value from another source 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 /.

I hope this provides a worthwhile alternative, and not just another syntax to confuse the discussion.

James Manger
(sent again after subscribing)

Received on Monday, 22 October 2007 03:24:15 UTC