2

I am learning JAX-RS, as an activity, I have created an endpoint which will list out all the TODO within by DB.

@Path("list")
@GET
public List<Todo> getTodos(){
    return todoService.getTodos();
}

The end point URL is

http://localhost:9090/hello-todo/api/v1/todo/list

Currently it lists all the TODO items, Since, I am learning query params I have decided to add add a condition to and list out only completed TODO items.

The end point URL is

http://localhost:9090/hello-todo/api/v1/todo/list?taskstatus=completed

The implementation method which I have written is @Path("list") @GET public List getFilteredTodos(@QueryParam("taskstatus") String taskstatus_){ return todoService.getFilteredTodos(); }

The build is fine, but while deploying it throws the below error:

The application resource model has failed during application initialization.

[[FATAL] A resource model has ambiguous (sub-)resource method for HTTP method GET and input mime-types as defined by"@Consumes" and "@Produces" annotations at Java methods public java.util.List academy.learnprogramming.rest.TodoRest.getTodos() and public java.util.List academy.learnprogramming.rest.TodoRest.getFilteredTodos(java.lang.String) at matching regular expression /list. These two methods produces and consumes exactly the same mime-types and therefore their invocation as a resource methods will always fail.; source='org.glassfish.jersey.server.model.RuntimeResource@8bd9d08']

I get that the deployement has failed as the both are having the same URI but how do I handle such a scenario?

Possible Solution:

@Path("list")
@GET
public List<Todo> getFilteredTodos(@QueryParam("taskstatus") String taskstatus_){
    if (taskstatus_!=null && !taskstatus_.isEmpty()) {
        return todoService.getFilteredTodos(taskstatus_);
    }else{
        return todoService.getTodos();
    }

}
User27854
  • 824
  • 1
  • 16
  • 40

2 Answers2

1

Possible solution: Implement one method with @Path("list") and handle the case with an empty taskstatus parameter value inside

skydriver
  • 11
  • 2
  • I have updated the question with a solution above. Is my implementation correct? – User27854 Jan 11 '22 at 12:46
  • You should also pass the `taskstatus` parameter to see which filter will you apply. – alexandrum Jan 11 '22 at 12:47
  • @alexandrum you mean the path should be corrected to @Path("list/{taskStatus}) wont this act as a parameter?. – User27854 Jan 11 '22 at 12:50
  • 1
    No, I mean the line with `return todoService.getFilteredTodos();`, you should also pass the parameter received such as: `return todoService.getFilteredTodos(taskStatus);` – alexandrum Jan 11 '22 at 12:51
  • 1
    @alexandrum thanks for pointing that out. I let me go and fix those code changes!! – User27854 Jan 11 '22 at 12:53
1

You can create something like:

 @GET
   @Path("list/{taskStatus}")
   public List getFilteredTodos(@PathParm("taskStatus") String taskStatus) {
      // do the filtering
   }

So you will have a different path that will not be conflicted with the main one.
More details here and here.

alexandrum
  • 429
  • 9
  • 17
  • taskstatus is a query parameter. But here we are handling it as a parameter. – User27854 Jan 11 '22 at 12:43
  • 1
    I understand, I just wanted to offer you another perspective. If it is mandatory to be a query parameter then you can go with the solution proposed by @skydriver and handle both cases within one method by checking the parameter received. – alexandrum Jan 11 '22 at 12:49
  • 1
    It should be a query parameter. – User27854 Jan 11 '22 at 12:51