users@jersey.java.net

Re: URI Matching

From: Marc Hadley <Marc.Hadley_at_Sun.COM>
Date: Fri, 02 Nov 2007 12:16:54 -0400

On Nov 2, 2007, at 11:18 AM, Alex McManus wrote:

> I have a query about URI matching; I'd be grateful for any help...
>
> Given the following example:
>
> @UriTemplate("widgets")
> public class WidgetList {
>
> @UriTemplate("latest")
> Widget getLatest() {...}
>
> @UriTemplate("{id}")
> Widget findWidget(@UriParam("id") String id) {
> return lookupWidget(id);
> }
> }
>
> ...which method should match a URI of "widgets/latest"? The
> specification suggests that it is random, given that matching methods
> are only sorted by input and output media type. Is this correct?
>
Its not random, 1.(j) in section 2.6 requires implementations to sort
matching sub-resource locators. The current rules would match "{id}".
This is actually inconsistent with 1.(d) which switches the primary
and secondary sort keys and I think the latter is correct and that 1.
(j) should be changed to match.

> I think this type of construct would be useful. If I have
> understood the
> spec correctly and this is not supported, I would like to propose a
> change: that when matching methods are sorted, it orders patterns
> with a
> smaller number of URI parameters ahead of those with more. In this
> case,
> "widgets/latest" (0 params) would be ordered ahead of "widgets/{0}" (1
> param).
>
I think we can get what you want with a slightly different algorithm
as described in 1.(d) for matching class level annotation.
Essentially the number of non-template var characters is the primary
key and the number of template vars is the secondary key. With this
you get:

"latest" > "lat{id}" > "{id}"
"{a}.{b}" > "{c}"

> Also, I'm confused by the example in section 2.1.1 of the spec. It
> states that methods annotated with @UriTemplate and **not**
> @HttpMethod
> are sub-resource locators, used to further resolve the object that
> will
> handle the request. Yet in the example (copied below), that
> description
> seems to apply to the getDiscounted() method, which is actually
> annotated with both.
>
> @UriTemplate("widgets")
> public class WidgetList {
> @HttpMethod
> @UriTemplate("offers")
> WidgetList getDiscounted() {...}
>
> @UriTemplate("{id}")
> Widget findWidget(@UriParam("id") String id) {
> return lookupWidget(id);
> }
> }
>
> If I understand this correctly, the @HttpMethod annotation should be
> applied to findWidget() and not getDiscounted()..?
>
I agree this is confusing and needs fixing. Having getDiscounted
should return a representation rather than an instance of a resource
class. E.g.:

@UriTemplate("widgets")
public class Widgets {
     @HttpMethod
     @UriTemplate("offers")
     WidgetList getDiscounted() {...}

     @UriTemplate("{id}")
     Widget findWidget(@UriParam("id") String id) {
         return lookupWidget(id);
     }
}

Where Widgets and Widget are resource classes and WidgetList is a
representation.

Thanks for the feedback, I'll create new issues to track these problems.
Marc.

---
Marc Hadley <marc.hadley at sun.com>
CTO Office, Sun Microsystems.