3

I have two REST end points, one to delete some data to all employees,and another to delete data for a specific employee by employee ID.

These are the two methods :

@Path("/{empId}/data")
@DELETE
public Response deleteEmpDataa(@PathParam("empId") final String empId) { }

@Path("/all/data")
@DELETE
public Response deleteAllData(){}

Now, when I want to delete all the employee data and make the query from postman chrome plugin

http://localhost/rest/mymapping/all/data

I expect it to call the second method deleteAllData. Instead it calls the first method with PathParam all.

Is this an ordering issue ? How do we fix this problem ?

Vinoth Kumar C M
  • 10,378
  • 28
  • 89
  • 130
  • If this is happening, than this is a bug against the spec. The second method should _always_ get hit, as it has the most literal characters, as mentioned [here](http://stackoverflow.com/a/32900799/2587435) – Paul Samsotha Nov 20 '15 at 13:51

3 Answers3

3

You need to use RegEx pattern to your @Path that delete an employee by id. For example, if your employee id is always a number, you can try something like:

@Path("/{empId:[0-9]*}/data")

Since 'all' is not numerical, the second Rest pattern will be called.

See: @Path and regular expression (Jersey/REST)

Community
  • 1
  • 1
JFPicard
  • 5,029
  • 3
  • 19
  • 43
2
  • all is a matching value for {empId}.
  • You do not treat an Employee as a true RESTful resource (not a good practice).

In your current implementation, you can:

@Path("/employees/{empId}")
@DELETE
public Response deleteEmpDataa(@PathParam("empId") final String empId) { }

@Path("/employees")
@DELETE
public Response deleteAllData(){}

And, with a better design, you would have:

@Path("/employees/{empId}")
public EmployeeResource getEmployee(@PathParam("empId" final String empId) {
  Employee e = loadEmployee(empId);
  return new EmployeeResource(employee);
}

and to delete all employees:

@Path("/employees")
@DELETE
public Response deleteAllEmployees() {
  // Delete all employees
  return Response.status(204).build();
}

and then EmployeeResource would be:

@Provider
public class EmployeeResource {
  private final Employee e;

  @DELETE
  public Response delete() {
    // Delete Employee
    return Response.status(204).build();
  }
}
nobeh
  • 9,784
  • 10
  • 49
  • 66
0

They are few rules in play when JAX-RS orders endpoints

  1. First of all, it sorts out all methods by number of literals (so your are the same, path expressions doesn't count here)
  2. Then it is sorted again by the number of template expressions, but in the descending order so /{emdId}/data/ takes precedence from /all/data.
Petr Mensik
  • 26,874
  • 17
  • 90
  • 115
  • In the spec the wording is _primary_ not _first_. There is a difference. It's short circuiting. If someone wins the primary, it stops there. What you are proposing is that the second sort causes the issue, which should not even be an issue at all if the implementation follows the spec – Paul Samsotha Nov 20 '15 at 14:04