dev@jsr311.java.net

Re: JSR311: Re: Error in JAX-RS method finding algorithm?

From: Marc Hadley <Marc.Hadley_at_Sun.COM>
Date: Mon, 11 Feb 2008 13:40:31 -0500

On Feb 11, 2008, at 1:22 PM, Bill Burke wrote:

> Still doesn't make sense to me. The spec nor these emails make it
> clear to me what we want. Do we want a method picked that most
> closely matches the preferred Accept header? Or do we want one that
> most closely matches the @ConsumeMime of a method? For example:
>
What I want the spec to say is first sort based on @ConsumeMime, i.e.
content type takes precedence. Then sort any equivalents from the
first sort based on @ProduceMime and the accept header. I think this
matches your second algorithm below.

Marc.

>
>
> method1: @ConsumeMime("text/*") @ProduceMime("text/html")
> method2: @ConsumeMime("text/xml") @ProduceMime("text/json")
>
> Accept: text/html, */*
> content-type: text/xml
>
>
> ACCEPT HEADER TAKES PRECEDENCE:
>
> Sort by consume:
>
> method2 "text/html"
> method1 "text/*"
>
> Then sort by accepts/produce:
>
> method1 "text/html"
> methdo2 "text/json"
>
>
> Method1 would be picked in the scenario even though the content-type
> matches method2 better. This gives precedence to the Accept
> header. As a method that does not more distinctly match the content-
> type will be chosen if there is a method that more distinctly
> matches the accept type. Is this the intended matching algorithm?
>
>
> OR
>
> Does the statement "most closely matches" omit method1 from the
> first sort list because it has wildcards? If so, we need a clearer
> algorithm. Something like:
>
> @ConsumeMime TAKES PRECEDENCE:
>
>
> So, I'm saying the algorithm should be:
>
> 1. Find all methods that could match based on content-type and
> accept headers along with produce/consume metadata
> 2. Sort list based on @ConsumeMime and RFC
> 3. Remove methods that are not as descriptive
> 4. Sort accepts header list base on RFC
>
> foreach accept header
> foreach remainingSortedMethod
> if method supports accept header, thats your pick
>
> This approach gives precedence to matching based on the content-type
> and @ConsumeMime metadata.
>
>
>
> Marc Hadley wrote:
>> On Feb 11, 2008, at 10:25 AM, Barry Fitzgerald wrote:
>>>
>>> I think there is an error in the algorithm in the JAX-RS specs for
>>> choosing the resource method (see bullet 2. in section 2.6)
>>>
>> I'm not sure but you may be looking at an older version of the
>> specification. The latest is linked from http://
>> jsr311.dev.java.net/. However I think your comment is still
>> relevant, more below.
>>> Consider the following scenario:
>>>
>>> I have a resource with 2 methods:
>>>
>>> @HttpMethod("GET")
>>> @UriTemplate("/users/{id}")
>>> @ProduceMime("text/xml")
>>> public Response getUser(@UriParam("id") String id) throws
>>> Exception { ....}
>>>
>>> @HttpMethod("GET")
>>> @UriTemplate("/users/{id}")
>>> @ProduceMime("application/json")
>>> public Response getUserJSON(@UriParam("id") String id) throws
>>> Exception { ....}
>>>
>>> If I then send a request to /users/24 with Accept headers of
>>> "text/xml, */*" one would expect the "text/xml" method to be
>>> invoked. However following the algorithm in the spec it is
>>> undefined which method should be invoked.
>>>
>>> More details:
>>>
>>> In the algorithm, both methods match the accept headers i.e. they
>>> are both added to the list of "matching resource methods" This
>>> list is then sorted using the consume mime type (not relevant in
>>> this case) and then by the produce mime. In this case it will
>>> compare "text/xml" against "application/json". As both are equally
>>> specific it is undefined which should be first.
>>>
>>> However surely as the "text/xml" method matches the accept header
>>> specifically it should always be returned first? See - http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html
>>> for further details
>>>
>>> One solution would be to change the algorithm to the following:
>>> • Sort the Accept header according to the W3 standards
>>> • Iterate through the accept header list. For each one:
>>> • Find all matching methods
>>> • If there is only one method return this and break out of
>>> the accept header loop
>>> • If there are multiple methods sort these methods using
>>> consume mime and produce mime. Then return the first.
>>> Therefore when accept header of "text/xml, text/*, */*" is sent
>>> in. Methods matching "text/html" are first searched for then "text/
>>> *" then "*/*". I think this would solve the problem.
>>>
>> You are describing the intended behavior, perhaps the spec could do
>> with some clarification. Section 2.5 step 3(b) says:
>> "Sort M using the media type of input data as the primary key and
>> the media type of output data
>> as the secondary key.
>> Sorting of media types follows the general rule: x/y < x/* < */*,
>> i.e. a method that explicitly lists one of the requested media
>> types is sorted before a method that lists */*. Quality parameter
>> values are also used such that x/y;q=1.0 < x/y;q=0.7."
>> The second paragraph is meant to cover your scenario. The getUser
>> method in your example explicitly lists "text/xml" from the accept
>> header so it would be sorted before the getUserJSON method.
>> Would the following modified first paragraph be clearer:
>> "Sort M as follows:
>> - The primary key is the media type of input data. Methods whose
>> ConsumeMime value most closely matches the media type of the
>> request are sorted first.
>> - The secondary key is the ProduceMime value. Methods whose value
>> of ProduceMime most closely match the value of the request accept
>> header are sorted first."
>> I will also add a reference to the appropriate section of the RFC
>> to the second paragraph.
>> Thanks,
>> Marc.
>>> This isn't some arbitrary obscure scenario.
>>>
>>> Looking at firefox's defaults it sends "text/xml,application/
>>> xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/
>>> png,*/*;q=0.5"
>>>
>>> Surely for a request from firefox I'd expect to get back one of
>>> the stated accepts not "application/widget" or "application/json"?
>>>
>>> Barry
>>>
>>>
>>>
>> ---
>> Marc Hadley <marc.hadley at sun.com>
>> CTO Office, Sun Microsystems.
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: dev-unsubscribe_at_jsr311.dev.java.net
>> For additional commands, e-mail: dev-help_at_jsr311.dev.java.net
>
> --
> Bill Burke
> JBoss, a division of Red Hat
> http://bill.burkecentral.com
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe_at_jsr311.dev.java.net
> For additional commands, e-mail: users-help_at_jsr311.dev.java.net
>

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