quarkus: JAX-RS Resource with multiple MediaTypes fails

Describe the bug When we annotate a JAX-RS Resource with @Produces({"application/json", "application/hal+json"}) It is not possible to access the resource with Header Accept: application/hal+json.

Expected behavior Server answers request with header Accept: application/hal+json with custom MessageBodyWriter

Actual behavior Server answers request with HTTP 406

Reason I did some debugging and could find the following: First Quarkus removes hal+ from application/hal+json and stores information in storedMediaTypes: https://github.com/quarkusio/quarkus/blob/8dc02652c058eeb92b0998293209509f2adb49ca/independent-projects/resteasy-reactive/common/runtime/src/main/java/org/jboss/resteasy/reactive/common/util/ServerMediaType.java#L91-L94

Then Quarkus checks differently in case multiple media types are annotated and then picks data from sortedMediaTypes instead of sortedOriginalMediaTypes which is used when only one media type is annotated. https://github.com/quarkusio/quarkus/blob/8dc02652c058eeb92b0998293209509f2adb49ca/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/handlers/ClassRoutingHandler.java#L121-L143

To Reproduce https://github.com/holomekc/multiple-mediatype-reproducer

working endpoint: uses media types: application/json and application/hal => HTTP 200

/failing endpoint: uses media types: application/json and application/hal+json => HTTP 406

Steps to reproduce the behavior:

  1. execute HTTP GET: http://localhost:8080/working
  2. execute HTTP GET: http://localhost:8080/failing

Configuration No configuration necessary

Screenshots (If applicable, add screenshots to help explain your problem.)

Environment (please complete the following information):

  • Output of uname -a or ver: Darwin xxxx 19.6.0 Darwin Kernel Version 19.6.0: Tue Nov 10 00:10:30 PST 2020; root:xnu-6153.141.10~1/RELEASE_X86_64 x86_64
  • Output of java -version: OpenJDK Runtime Environment Corretto-11.0.10.9.1 (build 11.0.10+9-LTS)
  • GraalVM version (if different from Java):
  • Quarkus version or git rev: 1.11.3.Final
  • Build tool (ie. output of mvnw --version or gradlew --version): 3.6.3

About this issue

  • Original URL
  • State: closed
  • Created 3 years ago
  • Comments: 16 (16 by maintainers)

Most upvoted comments

Opened the draft PR as suggested. You can see CI passes with that change, so that one should be fine.

But as mentioned above, while that fixes the issue of HTTP 406 being thrown, more work will be needed to ensure that RESTEasy Reactive actually handles compound media types such as hal+json properly.

Wow, that’s quite a question.

JAX-RS mentions suffixes by accident several times, but not what to do with them. It does however point out that XML serialisers should be registered with application/xml and application/*+xml, pointing out that there is some partial matching in the subtype, and that it’s not automatic: we can’t assume that application/foo+xml matches application/xml.

https://tools.ietf.org/html/rfc6838#section-4.2.8 says they’re names, to identify conformance to a format. So hal+json is really hal and the rest is informative.

HTTP matching doesn’t even mention them: https://tools.ietf.org/html/rfc7231#section-5.3.2

If it really is just informative, I guess that an accept of application/foo should match both application/foo+xml and application/foo producers, but not application/xml producers. But that’s conjecture: I can’t find relevant standard information.