W3C home > Mailing lists > Public > uri@w3.org > October 2007

Re: URI Templates - optional variables?

From: Mark Nottingham <mnot@mnot.net>
Date: Tue, 16 Oct 2007 11:03:35 +1000
Message-Id: <23043ECE-9F04-4BE3-A56F-C0272B057AFF@mnot.net>
Cc: URI <uri@w3.org>, Joe Gregorio <joe@bitworking.org>, Stefan Eissing <stefan.eissing@greenbytes.de>
To: "Roy T. Fielding" <fielding@gbiv.com>


On 16/10/2007, at 10:11 AM, Roy T. Fielding wrote:

> I think it is critical to limit the potential operations to
> typical string operations, both for simplicity of implementation
> and also for our capacity to understand the template without
> needing to refer to external rules or processing.  There is no
> reason to have URI templates if we don't limit them to a
> declarative syntax

Agreed; I didn't mean to imply anything else. My concern was more  
that we'd be able to cover the diversity of use cases we've heard  
about (much less hadn't come across yet) with a reasonably-sized  
library of operators in one go.

WRT "string operations": what about allowing variable values to be  
lists of strings? E.g., this seems like it would be useful:

template: http://example.org/sausage?{,&condiments}
condiments = ["tomato sauce", "chutney", "relish"]
result: http://example.org/sausage?condiments=tomato% 
20sauce&condiments=chutney&condiments=relish

Otherwise, I've got to define condiment1, condiment2, and so on, or  
fall back to simple substitution and build it myself.


>    {+separator|var1,var2,var3,...}              (join)
>       For each variable named in the comma-separated list,
>       if the named variable is defined and non-empty, then
>       substitute the concatenation of variable values separated,
>       if more than one substitution is made, with the string of
>       non-pipe separator characters between the '+' and '|'.
>          E.g., name     = "Fred"
>                age      = "41"
>                zip      = ""
>                location = "USA"
>         {+,|name,age,zip,location}    = "Fred,41,USA"
>         {+ish;|name,age,zip,location} = "Fredish;41ish;USA"
>         {+/|location,age}             = "USA/41"
>
>    {,separator|var1,var2,var3,...}              (param=value sub)
>       For each variable named in the comma-separated list,
>       if the named variable is defined and non-empty, then
>       substitute the concatenation of variable name, "=",
>       variable value.  If more than one substitution is made,
>       separate each substitution with the string of non-pipe
>       separator characters between the ',' and '|'.
>          E.g., name     = "Fred"
>                age      = "41"
>                zip      = ""
>                location = "USA"
>         {,&|name,age,zip,location} = "name=Fred&age=41&location=USA"
>         {,;|name,age,zip,location} = "name=Fred;age=41;location=USA"
>

So, I think it's worth diving into the encoding issue here again,  
because we still haven't quite nailed it. If I use a generic "join"  
operator, I can't get anything from reserved into the results -- even  
a comma. Also, keep in mind that what needs encoding will be  
different based upon where the template is in the URI, so we'll need  
some level of flexibility in this.

There are a lot of different ways we could address this. I'm thinking  
we could add an optional argument (e.g., a list of characters not to  
encode) to the operators; e.g.,

{,separator|var1,var2,var3,...|no_enc}

so you might have:

{,&|name,age,zip,location|,+} = "name=Fred 
+Smith&age=41&location=Nowhere,USA"

Alternatively, we could come up with a list of names for sets of  
characters that make sense to not escape in certain contexts.


> The main use case for substring substitution is to describe
> automated resource hierarchies that aren't flat, such as lists of
> users within a large intranet that are tree-balanced by splitting
> into sub-collections by the first character of the last name (this
> is a very common case at my work where thousands of users are often
> stored within a tree of JCR-based content).  Caches frequently do
> the same type of content balancing by splitting stored messages by
> the first few characters in a hash of the URI.  As Mark said, this
> could be accomplished by external processing of the original
> variable value, thereby defining a new variable to be used in the
> template, but then how do we describe such processing to readers
> of the URI template?  IMO, mapping values to identifier string is
> the whole point of this exercise, so any case that we don't handle
> within the declarative syntax is the same as punting to javascript.

Yeah. I'm starting to come around to the position that whatever can't  
be done by the operators we define just gets punted upstream into  
variable pre-processing, and that's it. That just makes it all the  
more important that we get the core 'library' of operators right,  
whilst leaving enough wiggle room for future extensions (likely, only  
by a standard, not ad hoc).


> One variation that might be worth considering:  If all of the map
> operators are delimited on both sides by a pipe character, as in
>
>     {variable}                  = "value"        or "red"
>     {|=red|favoritecolor}       = "value"        or "red"
>     {|<;name=|variable}         = ";name=value"  or ""
>     {|>.html|variable}          = "value.html"   or ""
>     {|+,|name,age,zip,location} = "Fred,41,USA"
>     {|,&|name,age,zip,location} = "name=Fred&age=41&location=USA"
>     {|-0-3|variable}            = "val"          or ""
>
> then the template processor need only special-case the pipe "|"
> and some people may find that easier to read.  *shrug*

I like it.

--
Mark Nottingham     http://www.mnot.net/
Received on Tuesday, 16 October 2007 01:05:34 GMT

This archive was generated by hypermail 2.2.0+W3C-0.50 : Thursday, 13 January 2011 12:15:37 GMT