users@jax-rs-spec.java.net

[jax-rs-spec users] [jsr339-experts] Re: Re: Matching Algorithm in Spec

From: Sergey Beryozkin <sberyozkin_at_talend.com>
Date: Thu, 16 Feb 2012 10:04:11 +0000

Hi Santiago

On 15/02/12 13:28, Santiago Pericas-Geertsen wrote:
> Hi Sergey,
>
> Inlined …
>
>>>
>>> description of this step. The original text handles the case of compatible types like:
>>>
>>> text/plain> text/*> */*
>>>
>>> quite well, but it's not precise when comparing incompatible types like:
>>>
>>> text/* ? application/xml
>>>
>>> Here a few interesting cases:
>>>
>>> (I) Request (Accept: text/plain, application/xml)
>>>
>>> Resource {
>>> @GET @Produces("text/*") m1() { ... }
>>> @GET @Produces("application/xml") m2() { ... }
>>> }
>>>
>>> Which method should be matched in this case?
>>>
>>
>> m2() : where is the ambiguity ? m2() has a clear priority, meaning it needs to be checked first and its media type will intersect OK with Accept and m1() needs to be discarded.
>

Sorry, the above actually gets m1() returned in our implementation which
I'm finding a bit unexpected, if I had one @Produces("text/plain") &
another one @Produces("application/xml") then it would be completely
unpredictable which method gets selected, but "application/xml" is more
specific than 'text/*' so it seems natural to me to get m2() returned...

> I'd call this vague in the spec, not ambiguous (i.e., there are cases that are ambiguous not matter how much text we add to the spec!). The only thing the spec said is that m/n> m/*> */*. Assuming a _fixed_ m and n (the most common interpretation), this does not establish any relationship between text/* and application/xml, as I explained in my original message. Thus, I don't think you can conclude that m2() should be chosen. In fact, I bet not all JAX-RS implementations match m2().
>
> The new text establishes a relationship even for incomparable types, like text/* and application/xml. It also factors q, qs and the distance of the matching; therefore, preferring types that are closer to what the client wants.
>
Sure - I'll read and get back with the comments
>>
>> The question is which method needs to be checked first in this case:
>>
>> @GET @Produces("text/*") m1() { ... }
>> @GET @Produces({"application/xml", "foo/*"}) m2() { ... }
>>
>> and similarly for methods which may have @Consumes.
>>
>> I'd suggest to clarify that when we have multiple methods with same HTTP verb then the one which has more non-wildcard values needs to be tried first during either Accept-_at_Oroduces or Content-Type-_at_Consumes intersections. Your example will be as well the one I added above would be 'taken care of' by this clarification.
>
> Check out the current proposal and tell me if there's any Accept header that wouldn't result in the expected method being matched in your example above. Just looking at the @Produces with more wildcard values does not work in general (like in the example below).
>
>>
>>
>>> (II) Same as (I) but with q=0.8 in Accept:
>>>
>>> Request (Accept: text/plain, application/xml;q=0.8)
>>>
>>> What about in this case?
>>>
>>
>> I actually see this one be more unpredictable, but I do not see anything ambiguous in the above JAX-RS example. As far as the client is concerned, it is fine with either type, As far as the JAX-RS code is concerned, the m2() needs to be checked first because it specifies a more specific media type. Thus application/xml needs to be returned/
>
> Actually, I know of users that would expect (after reading several e-mail threads), and implementations that would return, a text/plain response in this case. Rationale being that client prefers text/plain with q=1.0 and resource can produce text/*, and hence text/plain.
>
sorry again, this also works as you specify in our implementation...

Thanks, Sergey
> -- Santiago
>
>>> There are some other cases that are similar to these. In addition, there cases in which matching is clearly ambiguous for which the old algorithm was completely silent. The new one suggests that implementations issue a warning in these cases.
>>>
>>> Place take a look at the re-written step in [1] and provide feedback.
>>>
>>> -- Santiago
>>>
>>> [1] http://java.net/projects/jax-rs-spec/sources/git/content/spec/spec.pdf?rev=39d35e0fbf5949ba751a40b999900a4ed804852e
>>
>>
>> --
>> Sergey Beryozkin
>>
>> Talend Community Coders
>> http://coders.talend.com/
>>
>> Blog: http://sberyozkin.blogspot.com
>


-- 
Sergey Beryozkin
Talend Community Coders
http://coders.talend.com/
Blog: http://sberyozkin.blogspot.com