users@jersey.java.net

RE: URI Matching

From: Alex McManus <A.McManus_at_oclcpica.org>
Date: Mon, 5 Nov 2007 19:00:45 +0100

Hi Marc, Paul,

Thanks very much for your feedback, things are becoming clearer!

I think that what had also got me most confused was the difference
(conceptually) between a resource locator and a sub-resource method.
While the spec 2.6 1.j does sort according to the number of template
vars for sub-resource locators, I was looking at 2.6 2.a-c for
(sub-)resource methods which does not.

Is this also an error?

If I have read the spec correctly, then every request must terminate in
a match against a resource method (or sub-resource method) annotated
with @HttpMethod. This would clear things up for me; I was originally
thinking that a resource class itself could match and then be rendered
by an EntityProvider.

Thanks again for your help,

Alex.

-----Original Message-----
From: Paul.Sandoz_at_Sun.COM [mailto:Paul.Sandoz_at_Sun.COM]
Sent: 02 November 2007 16:34
To: users_at_jersey.dev.java.net
Cc: Alex McManus
Subject: Re: URI Matching

Marc Hadley wrote:
> 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.
>

0.4 of Jersey implements things 'correctly' such that a path
"widgest/latest" will invoke the getLatest method.

Alex, if you have the time i highly recommend you download Jersey 0.4
and modify the HelloWorld example to test things out.


>> 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}"
>

Right.


>> 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 have seen at least three times developers independently get confused
and wonder why a sub-locator is not working and it is because they have
an @HttpMethod as well as a @UriTemplate. I hope the refactoring of
@HttpMethod and @UriTemplate that we will implement in 0.5 will clear
things up a little:

   @Path("widgets")
   public class WidgetsResource {
       @GET @Path("offers")
       WidgetList getDiscounted() {...}

       @Path("{id}")
       WidgetResource findWidgetResource(@UriParam("id") String id) {
           return lookupWidgetResource(id);
       }
   }

Hmm... UriParam should perhaps be renamed to PathParam.

Paul.

> 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.
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
> For additional commands, e-mail: users-help_at_jersey.dev.java.net
>

-- 
| ? + ? = To question
----------------\
    Paul Sandoz
         x38109
+33-4-76188109