RE: draft-gregorio-uritemplate-03.txt

Comments on draft-gregorio-uritemplate-03.txt:

1. §4.5, 5th example
 http://example.org/?d={list|&d=|qux}

 http://example.org/?d=10&d=20&d=30

This example covers a common templating scenario: a query parameter that can repeat any number of times. However, it does not work well. When the variable value is undefined (or an empty list) you get
 http://example.org/?d=

but probably want
 http://example.org/

'...?d=' is likely to be interpreted as [ "" ] instead of an undefined variable.
Another flaw is that the query name 'd' is repeated in the template -- once outside the expansion and once inside.
The first flaw could be solved with '{-opt|?d=|qux}', but then both the query name 'd' and variable name 'qux' have to occur twice -- for a really simple common scenario. Repeating a name seems minor in this example (just a few extra characters), but once there are multiple parameters and longer names it is a recipe for unnecessary errors.

2.
"." and ".." values can have special meaning in a URI, acting much like reserved characters. Template expansion prevents variable values introducing the latter, but not the former.

3. Examples
The variable 'foo' has the value 'fred' in most examples, but in §4.5:
* 'foo' has a different value;
* a different variable ('bar') gets the value 'fred'; and
* 'fred' is also used as a variable name!
Argh. This just confuses the reader.
One set of variable names and values that all the examples use would be nicer. Choosing variable names that hint at their values (eg 'primes', instead of 'qux' for a list) would help. For instance:

userid  = [ "fred" ]
primes  = [ "2", "3", "5" ]
amount  = [ "2,300.50" ]
zero    = [ "" ]
emp     = [ ]
res     = [ "Ben & Jerry's a/b/c" ]
i18ns   = [ "\u017F\u0307", "\u03d3" ]
1-a_b.c = [ "200" ]
un is undefined

4.
§4.4.1 ('var') substitution does not say what to do if the value is a list. I suggest concatenation the values with no separator. Example: "{primes}" -> "235".

5.
Perhaps the most common scenario will be a URI template with lots of optional query parameters: some param names matching the variable names, others not; some params that can be repeated, most occurring at most once. It should be straight forward to write such a template, but I don't think it is with this syntax.
http://example.org/stuff?{join|&|userid,amount}{-prefix|&n=|primes}{-prefix|&org=|res}

The template author has to accept:
* A trailing '?' when no optional params are present
   "http://example.org/stuff?"
* An unusual '?&' pair when the single-valued same-name params are absent
   "http://example.org/stuff?&n=2&n=3&n=5"

6.
Another common scenario will be a single optional query parameter. For instance, getting data in XML (default) or JSON (?fmt=json) format.
  http://example.org/data

  http://example.org/data?fmt=json

A template author could support this with one expansion:
  http://example.org/data{-prefix|?fmt=|fmt}

This can produce ".../data" and ".../data?fmt=json" as desired.
However, it can also produce
  http://example.org/data?fmt=json?fmt=123?fmt=abc

when a variable value of [ "json", "123", "abc" ] is supplied.
This is unlikely to be what the server was expecting. It introduces reserved characters '?' and '=' in a place that was probably not anticipated (a query param value). It also requires the 'fmt' name to be included twice.
A better template would be:
  http://example.org/data{-opt|?fmt=|fmt}{fmt}

This works, but now the author needed 2 expansions and to include the 'fmt' name 3 times.
6b.
The pattern of an optional single item that needs a prefix or suffix when present will be common. The prefix and suffix operators will seem like the right solution to many authors. They are the simplest solution (1 expansion) that works with "good" data (variable values that are undefined or a single string). But this simplest solution is insecure as by using a "bad" value (a list of 2 or more strings) the prefix or suffix (often containing reserved chars) is repeated. This undermines the design criteria of the author controlling where reserved chars go.
The author could be more careful, but the spec should be able to make the careful choice the simplest.

7.
The sample parsing code in §7 does not appear to preserve the order of the variables. However, the order "MUST be preserved" for the 'join' operator (§4.4.6). I don't know Python well. Is there any easy way to return the variables (& their defaults) and a list (or two lists: names & defaults), instead of as a dictionary/map/associative-array?

8.
The rule to reject the whole template when an unrecognized operator is present (§4.4) will make it hard to introduce new operators. There is no version negotiation as a URI template is a simple data syntax, not a protocol.
I think it would work better if an unknown operator was treated like an undefined variable, and replaced with the default value (or an empty string). This does not work with the current syntax, but it could work with other schemes.

9.
Every operator that supports lists, explicitly treats a variable that is undefined or an empty list identically. I agree with this. §4.1 says the opposite: "A list variable that contains no members ... MUST NOT be considered undefined". I suggest changing this sentence.

10.
How about a 'query' operator, instead of 'join'.
  data?{-join|&|userid,amount}
becomes
  data{-query||userid,amount}
where the template processor can take care of choosing a '?' or '&' as a prefix (simply depending on whether or not a '?' already appear in the URI being constructed). Perhaps '?' would be a better operator name than 'query'.
We could allow values to be lists.
  {-query||primes,userid} -> "?primes=2&primes=3&primes=5&userid=fred"
The arg could be used as the query param name (instead of reusing the variable name) when it isn't the empty string.
  {-query|n|primes} -> "?n=2&n=3&n=5"
A non-empty arg with more than one variable would be unusual but still obvious.
  {-query|x|userid,amount} -> "?x=fred&x=2%2C300.50"
  {-query|u|userid}{-query|a|amount} -> "?u=fred&a=2%2C300.50"


OVERALL
A lot of common scenarios are awkward to support cleanly with the current syntax.
A lot of simple scenarios require multiple expansions and repeated names, which make the syntax ungainly. This should not be necessary.

A syntax with hardwired support for a prefix, suffix, separator, default and variable name can be much cleaner - particularly for template authors. It would not have named operators so one avenue of extensibility is cut off, but this is not crucial. There is plenty of room for extensibility in the variable names.

TYPOS
§1.3  s/nor should not be/nor should they be/
§4.1  s/must comde from/must come from/
§4.4.7  s/listjoin/list/

----------
From: uri-request@w3.org [mailto:uri-request@w3.org] On Behalf Of Joe Gregorio
Sent: Saturday, 5 April 2008 7:19 AM


Draft 03 of the uri template spec has been published:

   http://www.ietf.org/internet-drafts/draft-gregorio-uritemplate-03.txt

Received on Wednesday, 9 April 2008 01:58:13 UTC