-
Notifications
You must be signed in to change notification settings - Fork 125
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Clarification: Ordering of media types with parameters #945
Comments
Just to be clear, these two sections are there for different purposes. Section 3.7.2 is about matching and Section 3.8 about determining the media type of responses (way after matching, of course).
Section 3.7.2 only deals with
What use case would this new rule be applicable for?
So the intent here would be to have two resource methods one with and one without |
My intent is indeed to make the params part of the matching process as well as the response media type determination. I'll try to illustrate the need for this with some examples (written freehand so forgive any minor mistakes). I'll continue with the @Path("examples")
public class Example {
@GET
@Produces("text/plain;format=flowed;qs=0.8")
public String fixed(){
// some implementation that returns fixed-format text
}
@GET
@Produces("text/plain;format=fixed")
public String flowed(){
// some implementation that returns flowed-format text
}
} With this setup, if you do a GET request to "/examples" with Accept header set to @Path("examples")
public class Example {
@GET
@Produces({"text/plain;format=flowed;qs=0.8","text/plain;format=fixed"})
public String fixed(@Context Request request){
// availableVariants is a list of 2 variants, one for each of the media types in Produces (bit much to write out in code)
Variant selected = request.selectVariant(availableVariants);
}
} In this example, I hope that these example help illustrate the need to distinguish media types based on the parameters as well. With the I hope this answered the questions you asked. If anything is still unclear, please let me know. |
Correct.
Yes, except the client can always use
Yes.
I certainly understand where you're coming from. But, every addition brings additional complexity to the algorithm and, to be honest, the benefits seem very small in this case. Most scenarios can be deal with some use of |
Thanks for the clear and concise responses. It really helps with ensuring that the message came across well.
This part is unclear to me. In my example, the client requests the Would it work if I explicitly specify the fixed format at a lower priority in my Accept header? Something like As to whether the additional complexity is beneficial, I think the fact that this is included in the algorithm for the Accept header (in the HTTP spec) is an indication that it is. Especially since JAX-RS is intended to work with HTTP content negotiation (which uses the Accept header). But as you said, it's good to get input from others on this. |
Yes, you're correct, the default value of
Right, this is how you'd need to do it. This should work if the implementation follows the algorithm in the spec.
Yes, it's a workaround, but you're use case is far from common.
As I said, I'd like to hear the opinion of others here. |
It doesn't seem like anyone else has been able to give their opinion yet. But I've been trying out this workaround (in Jersey), and it doesn't seem to work that well. When I have a JAX-RS method that produces both media types, the And when you have separate JAX-RS methods for each media type, the problem gets even bigger. Since the JAX-RS matching algorithm doesn't consider the media type parameters as differentiating factors for media types, Jersey considers those separate JAX-RS methods as producing the same media type. So when the JAX-RS application is started, it fails with the following error. Since it's not possible to create separate JAX-RS methods for each media type and I hope that we can soon get feedback from others on this. Do people need to get notified to provide this feedback, or does it just take time? |
I agree with @spericas that the actual benefit of supporting this case is rather small. However, given the fact that the HTTP spec explicitly mention this kind of ordering, it may be worth to support it. See: https://www.rfcreader.com/#share60ab9039ff7fe20a44dba01e_line1712 |
@chkal Thanks for your input on this. I appreciate that you think this is worth supporting due to it being explicitly part of the HTTP spec. But I still want to explain why I think the benefit of supporting this use case may actually be bigger than you expect. Though it's more a matter of the drawback of not supporting this use case being more problematic than you might expect (I emphasized it in the text below, if you want to skip the recap which I added for clarity). To recap, the problem here is that the JAX-RS spec ignores the media type parameters when comparing media types. This results in the JAX-RS algorithms simply using the first media type in the list, even when media types with better matching parameters are available. The workaround suggested by @spericas was to have the client add the non-preferred media types to the HTTP Accept header with a much lower q-value. Unfortunately, this doesn't seem to work. It works when matching a request to a method but not with the @Path("examples")
public class Example {
@GET
@Produces("text/plain;format=flowed;qs=0.8")
public String fixed(){
// some implementation that returns fixed-format text
}
@GET
@Produces("text/plain;format=fixed")
public String flowed(){
// some implementation that returns flowed-format text
}
} As it turns out, this implementation is actually not possible (at least with Jersey). The problem is that, since media type parameters are ignored, these 2 methods are considered to have the same value for @Path("examples")
public class Example {
@GET
@Produces({"text/plain;format=flowed;qs=0.8","text/plain;format=fixed"})
public String fixed(@Context Request request){
// availableVariants is a list of 2 variants, one for each of the media types in Produces (bit much to write out in code)
Variant selected = request.selectVariant(availableVariants);
}
} With this, the application starts up correctly but you have to determine inside the method which media type was actually resolved in order to return the correct media type. For this, you have the The only way I have found to get the best matching media type, taking into account its media type parameters, is to write my own code for this in the API. And the problem with this is that there is no way, that I have found at least, to get the producible media types for a request from the JAX-RS application. So you also have to use reflection to scan for the This brings me to the big drawback of not supporting this use case. With the situation being as I explained above, it essentially makes media types like These media types use the I hope that supporting such media types that are intended REST APIs, just like JAX-RS, is considered a sufficient benefit to support this use case. |
I recently noticed that this same problem was reported for Spring MVC. I'm mentioning it because I think it shows that this is a fairly common use case that is currently not being supported (by either JAX-RS or Spring). This issue can also be stated as an inconsistency in the spec itself. Appendix B states that the HTTP |
Is there any update on this? I noticed that the Spring issue has been closed without any changes being implemented for it. But the issue itself does contain a lot more real-world use cases and links many other issues that are created, e.g. for application servers that provide implementations for both JAX-RS and Spring. This shows that this is indeed a problem that users are having. |
I think a clarification is needed in the JAX-RS specification when it comes to dealing with media types that may include parameters. I'll refer to the 3.0 specification but, if possible, this clarification would also be useful in the 2.x specification.
From the JAX-RS 3.0 specification (chapter 3.7.2, step 2b)
From the JAX-RS 3.0 specification (chapter 3.8, step 7)
Both the request matching and media type determining algorithm require the media types to be sorted in descending order of specificity. This is described as
n/m > n/* > */*
in both algorithms. However, this does not cover the usage of parameters in media types. I think a clarification is needed to describe how exactly to sort a media type that has parameters.My own interpretation is that a media type with parameters is more specific than a media type with parameters. So I would clarify this by describing the sorting as
n/m;a=b > n/m > n/* > */*
. This also matches the algorithm defined for theAccept
HTTP header:If this clarification is added, this may also need to included in the TCK to ensure consistency in the implemented algorithms.
Currently, the implementation in Jersey 2.x ignores all parameters except
q
andqs
(and maybecharset
) in these algorithms. Sotext/plain;format=flowed
is considered equivalent totext/plain
and would be sorted on the same level. I expect this to still be the same in Jersey 3.x though I have not tested that.I noticed that #446 is somewhat related. It covers some other points as well but also highlights this problem
Since that issue was much older and did not cover this problem explicitly, I created this new issue instead of adding to that older one.
The text was updated successfully, but these errors were encountered: