users@jax-rs-spec.java.net

[jax-rs-spec users] Re: Digest for list users_at_jax-rs-spec.java.net

From: Ron Sigal <rsigal_at_redhat.com>
Date: Sat, 07 Dec 2013 16:55:13 -0400

Hi Santiago,

Thank you for your response.

I was surprised that the algorithm in Section 3.8 of the JAX-RS spec
seems to be inconsistent with the algorithm implicit in
http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.1, which I
described on RESTEASY-994 as

    1. Let PO = the partial order on accepted media types induced by "is
    less specific than".

    2. Add "dummy/dummy;q=0" as the minimal element in PO, where
    "dummy/dummy;q=0" is a wildcard like "*/*"

    3. For each M in available media types:
           Let Q_M = max { q | q is the quality factor of a maximal
    element in PO }

    4. Let Q = max { Q_M | M in available media types }

    5. Let MT = { M | M is an available media type such that M_Q = Q }

    6. If no element in MT matches an accepted media type, return a
    "406" response.

    7. Return an arbitrary element of MT

Actually, there are a couple of gaps in
http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.1:


1. There is no mention of tie breaking in the case that multiple
available media type are assigned the same quality factor. I think that
the consensus on RESTEASY-994 is that the available media type that
matches the more specific requested media range should be given
preference. For example, given

    Accept: application/json, */*

application/json and application/xml would both have a quality factor of
1.0, but application/json should be preferred. Step 7 could be changed
to implement tie breaking based on specificity.


2. There is no precise definition of "more specific". For example, I
would expect application/json to be more specific that */*;a=1;b=2;c=3,
but Resteasy currently prefers the latter because it counts the number
of parameters. I think that should be changed with the ordering defined:

    media type 1 is more specific than media type 2 if and only if

    * media type 1 has a non wildcard type and media type 2 has a
wildcard type, or
    * media type 1 has a non wildcard subtype and media type 2 has a
wildcard subtype, or
    * media type 1 has more parameters than media type 2


3. It's a minor thing, but there's no suggestion for what to do with

    Accept: application/json, application/xml, application/json;q=0.5


Anyway, the way things are, Request.selectVariant() is governed by
http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14 (I guess),
and negotiation based on the @Produces annotation is governed by Section
3.8 of the JAX-RS spec, and I believe they can legally return different
results. In particular, the JAX-RS algorithm doesn't have a notion of
basing the quality factor of an available media type on the most
specific matching requested media range. For example, given the
somewhat artificial case

    Accept; application/json;q=0.5, application/*

and

    @Produces("application/json, application/xml")

the HTTP algorithm would assign a quality factor of 0.5 to
application/json because application/json;q=0.5 is more specific than
application/*, but the JAX-RS algorithm gives

    M = { S("application/json;q=0.5", "application/json"),
S("application/*", "application/json"), S("application/*",
"application/xml")
      = { application/json;q=0.5, application/json;q=1.0,
application/xml;q=1.0 }

where

application/json;q=1.0 >= application/xml;q=1.0 > application/json;q=0.5

and

application/xml;q=1.0 >= application/json;q=1.0 > application/json;q=0.5

are both legal orderings, so that either application/json or
application/xml could be returned.


-Ron


On 12/07/2013 05:15 AM, users-request_at_jax-rs-spec.java.net wrote:
> Hello Ron,
>
> We spent some time evaluating our algorithm and found that it returns
> the expected result in the majority of cases. This one is a bit tricky
> because there's an overlap between the accept type patterns, and that
> typically results in ambiguity and less than ideal results.
>
> If anyone has a suggestion on how to improve the algorithm (while
> keeping it simple!), we should file a JIRA for an update release.
> Designing a simple algorithm that will result in the expected results
> for all possible cases (including the one in question) isn't easy, but
> there's always room for improvement, of course.
>
> Thanks.
>
> -- Santiago