URI Templates: {prefix^variable*separator^suffix|default}

Next modification of my proposal:

{ prefix[^] variable [*separator] [^suffix] [|default] }

If <variable> is undefined, replace with
  <default>
If <variable> is a single value, replace with
  <prefix><variable><suffix>
If <variable> is a list of 2 values, replace with
  <prefix><variable[0]><separator><variable[1]><suffix>

A <prefix> in the form ?name= or &name= is treated specially.
If no question mark already appears in the URI under construction, for the prefix use
  ?<name>=
Otherwise, for the prefix use
  &<name>=

There are some shortcuts for convenience:
{prefix^var*} is a shortcut for {prefix^var*prefix}, which is useful for query parameters that can repeat.
{prefixvar} is a shortcut for {prefix^var}, but is only allowed if unambiguous (eg <prefix> ends with a <reserved> character).
{varsuffix} is shortcut for {var^suffix}, but is only allowed if unambiguous (eg <suffix> starts with a <reserved> character other than * and contains no <alpha> chars). {/name/} -> /alice/
{?name=} and {&name=} are shortcuts for {?name=name} and {&name=name}.
Omitting <default> or <suffix> is a shortcut for including them as an empty string.

Different dividers, different orders, different character sets, different defaults or different shortcuts are conceivable -- but don’t fundamentally change this syntax.
It can be parsed with a regular expression.


EXAMPLES (converted from other proposals):

http://www.google.com/notebook/feeds/{userID}{/notebooks/notebookID}{/-/categories*/}


http://bitworking.org/news/{entrypath*/}


http://bitworking.org/projects/sparklines/spark.cgi?step={step|2}{&d=}{&type=smooth}{&height=}{&limits=}{&min-m=}{&max-m=}{&last-m=}{&min-color=}{&max-color=}{&last-color=}


http://code.google.com/p/{project}/

https://{project}.googlecode.com/svn/trunk

http://docs.google.com/a/{domain}/

mailto:{userid}@{domain}

/atom/everything{?tag=}{&sortfields=}{&sortorder=}{&search=}{&casesensitive=}{&nodetype=}{&page=}{&ps=}

/service/{format}/{view}{/sub}{?activityUuid=}

/{handle}/{view}/{collection}{?search=}{&tags=}{&page=}{&ps=}

http://example.com/{(parens)foo}

http://example.com/{name1}{+name2}

http://example.com/{name1}{&name2}

http://example.com/{names*+}


{?start=}{&count=}{&tag=tags*}

http://search.yahooapis.com/WebSearchService/V1/webSearch?appid={yahoo:appid}&query={searchTerms}{&results=count}{&start=startIndex}



I suspect a fair few people would not even have to read the template spec to understand which URIs can be built from the bulk of these templates. Many templates will be valid URIs plus braces.

The following Java regular expression parses this syntax. It is not trivial, but not diabolical either.

        public static final Pattern REGEX = Pattern.compile(
            "\\{" +                             //   {
                "([^\\^\\|\\}]*?)\\^?" +        // 1  prefix ^
                "(|[a-zA-Z][a-zA-Z\\._~-]*+)" + // 2  variable
                "(?:\\*([^\\^\\|\\}]*+))?" +    // 3  * separator
                "(?:([^\\^a-zA-Z\\._~-][^a-zA-Z\\^\\|\\}]*+|" + // 4  suffix
                "\\^[^\\^\\|\\}]*+))?" +        // 4  ^ suffix
                "(?:\\|([^\\}]*))?" +           // 5  | default
            "\\}");                             //   }

Received on Monday, 12 November 2007 06:25:59 UTC