I cannot get to the correct @Path

Using JAX-RS, I have the following 3 @Path

s.

@Path(JobRest.PATH)
@Api(value = JobRest.PATH, description = "REST APIs for Jobs")
public interface JobRest {
    public static final String PATH = "/job";

    @GET
    @Path("/last")
    @Produces(MediaType.APPLICATION_JSON)
    public Job retrieveLastJob(...);

    @GET
    @Path("/{jobId}")
    @Produces(MediaType.APPLICATION_JSON)
    @Consumes(MediaType.APPLICATION_JSON)
    public Job retrieveJob(...., @PathParam("jobId") String jobId, );

    @GET
    @Produces(MediaType.APPLICATION_JSON)
    public JobList retrieveAllJobs(....);
}

      

  • /job

    correctly calls retrieveAllJobs()

  • /job/1236

    calls correctly retrieveJob(..., "1236", ...)

    .

I expected /job/last

to call retrieveLastJob(...)

as it matches, but it calls instead retrieveJob(..., "last", ...)

.

How do I change the notation to /job/last

call retrieveLastJob(...)

?

+3


source to share


1 answer


TL; DR

Remove @Consumes(MediaType.APPLICATION_JSON)

by method retrieveJob

. First, he does not accept the body, so he does not consume anything. Second, it is contrary to expected behavior.


I've tested with both Jersey and RESTeasy and it seems to be an implementation difference. Jersey works great with your code, while RESTeasy always refers to the method retrieveJob

as you go through.

Here's my take. If you look at the JAX-RS spec; 3.7.2 Match Query , there is a semi-critical algorithm for matching resources that looks something like this.



  • Get all the corresponding resource class (along the way), put them in a set.
  • Get all the matching resource methods (along the way), put them into a collection.
  • Sorting methods using the best matching path (most literal characters come first).
  • Sort by media type (with consumption and performance).

From my point of view, in this particular case, after step 3, it retrieveLastJob

should automatically win as it has the most literal symbols. The types of media generated are the same and the type of consumables shouldn't matter as this is a GET request without Content-Type for any match.

My guess is that RESTeasy still uses annotation for sorting, even though it shouldn't be taken into account in this case. So it seems that the annotated method gets more priority as it appears to be more specific just by having the annotation and the other doesn't. But in this case, the level of specificity (step 4) really doesn't matter.

I don't know if this is a bug against spec. It is not very clear how this should be handled, but I personally believe that Jersey's behavior is the correct behavior, since the fact that this level of specificity is irrelevant in this particular case. It's not correct to have an annotation @Consumes

anyway for a GET request without a body anyway.

+3


source







All Articles