Re: URI Template -04 Implementation Notes

I am trying to reconcile URI Templates with the apparent lack
of consensus on the more complex features.  I guess that confusion
shouldn't be surprising, since I forgot that I hadn't included
definitions for each of the operators in draft 04 (sections 3.7-10),
and then all my spec plans were discarded when my son was born the
following week.

One of the big problems seems to be wherever template variables
make reference to implementation language types, like lists or
structures, where everyone seems to have a different opinion on
how to handle empty (or zero member) values.  Likewise, I thought
that the explode syntax would be valuable for expressing many-variable
templates in a very short string, but it seems to add too much
complexity to the implementations.

On Jun 1, 2010, at 9:00 PM, Joe Gregorio wrote:

> I've committed an incomplete implementation of the -04 spec
> in Python to svn along with test cases taken from the spec.
> 
>   http://code.google.com/p/uri-templates/source/detail?r=57
> 
> The tests themselves are taken directly from the spec and
> are stored in a JSON file, to make it easier to reuse them.
> (Well, almost taken verbatim from the spec, below I list
> the cases that were either inconsistent or looked wrong
> and how I changed them.) The code does not implement
> 'partial' modifiers.

Can you say why it does not implement partials?  That should
be one of the easiest things to implement, and yet two people
didn't bother.

> Here are my notes:
> 
> 1. The spec is fiddly, by which I mean that while the rules
>   for handling semicolon, query parameter, path and label
>   expansions all make sense on their own, they are all
>   slightly different from each other. It makes for a lot
>   more code than I expected, and is fairly tedious to implement.
>   I'm not sure that the amount of complexity is warranted.

The goal is to make them consistent with the way that the
same syntax is handled on websites.  Semicolon, query, labels,
and paths have distinct parsing behavior on websites regardless
of templates.

Looking at your implementation, I think the tedious bit is due
to the special handling of lists and modifiers, not the different
behavior of operators.

>   To simplify I would like to see label and semicolon path
>   style expansions dropped. I also believe the '+' modifier could
>   be dropped without loss of generality.

I don't think that makes any sense.  Label and params are the
two most common variations on path selectors (e.g., Apache Sling,
Rails, etc.).  Having them as operators allows the ";" or "." prefix
to be elided when optional, and multiple values to be properly separated.
Trying to define URI templates without them will just eliminate
templates as a viable description for those resources.

> 2. From the spec, this rule isn't consistent:
>      ["{?x,y,empty}", "?x=1024&y=768&empty="],

It is consistent with HTML forms.  When a form variable is empty, it
is submitted as name=

> 3. One of these is inconsistent
>     ["X{.empty}", "X."],
>     ["x{?empty_list}", "x"],

I made a distinction between empty string and empty list.  I should
just remove lists and exclude empty labels.

> 4. Also inconsistent
>     ["{;list}", ";val1,val2,val3"],
>     ["x{;name=none}", "x;name=Fred,Wilma,Pebbles"],

Yes, the second was intended.

> 5. I tried working through the empty and default cases
>    (section 2.5) but came across so many cases that
>    seemed to disagree with previous examples or the wording
>    of the spec that I began to suspect the section was incomplete.
>    Here is the list of test cases I had collected and believe are wrong,
>    before I stopped:
> 
>     ["x{empty_list=_}y", "xy"],
>     ["x{empty_list+=_}y", "xempty_list._y"],
>     ["x{empty_keys=_}y", "xy"],
>     ["x{empty_keys+=_}y", "xempty_keys._y"],
>     ["x{?empty}", "x?empty="],
>     ["x{?empty=none}", "x?empty="],
>     ["x{?empty_list*=none}", "x?none"],
>     ["x{?empty_list+=none}", "x?empty_list.none"],
>     ["x{?empty_keys*=none}", "x?none"],
>     ["x{?empty_keys+=none}", "x?empty_keys.none"],
> 
>  I believe many of these cases with defaults are ones that Mike Burrows
>  raised earlier.

Yes, they are all due to the distinction between empty strings and
empty lists, and when lists are expanded versus just treated as another
string.  The missing prose doesn't help, but the easier solution
is to remove those as options.

> 6. I've come across yet another case where going in reverse, from a template
>   to matching, would be useful. How about carving out () at the end of
>   an expression as a place where a regex could be stored for applications
>   that want to use a template for matching against incoming requests, but
>   just state that the allowed regex's and matching algorithms are outside
>   the scope of the current spec?

I don't think so.  A regex can be derived from the template if the expressions
are delimited by reserved characters and reserved substitution is not used.
If those two conditions are not true, then a matching regex would have to be
ambiguous, which won't satisfy anyone.  I think we should just say what
people should limit their template to if they want it to be matching.

I am also leaning toward making the reserved expansion "+" operator
a prefix on any variable, since that would be backward compatible with
simple expressions and yet give people the rope they want to hang other
values on without complicating the implementations further.  We can then
move the encode-reserved question inside the value-substitution routine
rather than being operator-specific.

....Roy

Received on Thursday, 16 September 2010 01:29:24 UTC