0

Day 1: Added below rest endpoint for delete operation.

@Path("/company/v1/department") @Component public class ManageResource { @DELETE @Path("/{identifier}/{identifier_value}/employee") public void delete(@PathParam("identifier") String identifier, @PathParam("identifier_value") final String identifierValue, @QueryParam("age") final String age) { //delete operation } } 

I was able to invoke DELETE endpoint using postman with below request:

DELETE: http://localhost:8080/company/v1/department/name/baner/employee?age=50 

Day 2: Added below rest endpoint for the update operation in the same resource.

@Path("/company/v1/department") @Component public class ManageResource { @DELETE @Path("/{identifier}/{identifier_value}/employee") public void delete(@PathParam("identifier") String identifier, @PathParam("identifier_value") final String identifierValue, @QueryParam("age") final String age) { //delete operation } @PUT @Path("/empid/{value}/employee") @Consumes(MediaType.APPLICATION_JSON) public void update(@PathParam("value") final String identifierValue, @RequestBody final EmployeeUpdateRequest request) { //update operation } } 

After adding this new endpoint, I am able to invoke PUT using postman with below request:

PUT: http://localhost:8080/company/v1/department/empid/epid-123/employee { //Json request body } 

But when I try to invoke Delete endpoint it is giving me 405 (Method Not Allowed) error. If I comment my new Put method, then the Delete method works fine. Also, if I replace Path for Put method to "/{identifier}/{identifier_value}/employee" then both Delete and Put method works fine.

I am using Jersey 1.19 with tomcat. Can someone help me with this?

1 Answer 1

1

Your Paths are in conflict with each other. Let me try to explain:

DELETE = /{identifier}/{identifier_value}/employee PUT = /empid/{value}/employee 

That means when we evaluate the path from left to right, we can either have {identifier} which is anything or "empid" which is a fixed string

Jersey always tries to find the "most perfect" match for a REST endpoint. It does so by evaluating the path from left to right. Fixed strings always take precedence before random variables!

Basically that means when you want to call a DELETE, you cannot have the value "empid" for the variable "{identifier}" because then you are already out-of-scope

So the DELETE call to

http://localhost:8080/company/v1/department/empid/empid-123/employee 

will not work as Jersey had to make a decision whether "empid" in the request matches "{identifier}" (DELETE) or "empid" (PUT). And as i tried to explain above, fixed strings take a higher priority. In contrast, any other DELETE request where

http://localhost:8080/company/v1/department/{identifier}/empid-123/employee 

and

{identifier} != "empid" 

works.

Possible solution:

make your rest endpoints resource-oriented

DELETE: /employee/{employee-id}

PUT: /employee/{employee-id}

Notice how the endpoints are identical, since other than the ID in most systems, no information is needed to identify an entity.

Sign up to request clarification or add additional context in comments.

1 Comment

First of all thanks for the answer. I understood about how URLs precedence has a role in this but what I didn't understand is that why is not considering HTTP method as well. Both the request methods are altogether different so it should not be confused about selecting proper resources. Maybe I am wrong but the logic for finding correct resource seems to be buggy to me. If I had 2 DELETE resources with path mentioned above (I mean if I replace PUT with DELETE) then, of course, it would be difficult to resolve the path but that's not the case here.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.