erp erp - 4 months ago 29
Java Question

Overloading a REST endpoint with different QueryParams

I am trying to determine the best way to interact with a Jersey Client endpoint with a variable being

Collection<String>
. I am not 100% sure this would be correct to do it but I was wondering if this is possible/what is the correct way to achieve this - maybe a
@POST
with a message body?

The method in my
DAO
is
Set<Foo> retrieveByKeys(Collection<String> keys)
. As a result I am trying to figure out the best way to create an endpoint for this. First thought was:

@POST
@Path('/foos')
@Consumes(MediaType.APPLICATAION_JSON)
@Produces(MediaType.APPLICATAION_JSON)
Response retrieveByKeys(Collection<String> keys) {
... //do things
}


OR:

@GET
@Path('/foos')
Response retrieveByKeys(@QueryParam('keys') Collection<String> keys) {
... //do things
}


I'm not too sure that you can do the second one but has been suggested as a possible solution.

This is fine either way, but at the same time I have another method in my
DAO
that is
List<Foo> retrievePageStartingFrom(String startKey, int pageSize)
. I know it is best rest practice to reuse urls when possible, which is what I am trying to do with these two. I am just struggling to find a way to differentiate the two methods but keep the same url.

I was wondering if it is possible to overload the endpoint with other
@QueryParams
but this time like:

@GET
@Path('/foos')
Response retrievePageStartingFrom(@QueryParam('startKey') String startKey, @QueryParam('pageSize') int pageSize) {
... //do things
}


And that the Jersey Client would know to differentiate the two calls because the first method has one parameter and the second method has two parameters which are different types also.

I guess the best way what I am thinking I am trying to do is like in java when you can have one constructor with certain parameters, and another constructor with different/different types of parameters but the same method name (obviously).

Regardless of what the right answer is I am trying to keep the same URL for the two methods if possible and I'd like to know what would be the best way to achieve that! thx.

Answer

No, It's not possible to overload your endpoint methods if all of them are using same HTTP methods(e.g. all with @Get Annotation) but different query parameters . Rest resources are uniquely identified by the URI not by the params.

what you need to do is check presence of different query parameters and call desired implementation:

@GET
@Path('/foos')
Response retrieveByKeys(@QueryParam('keys') Collection<String> keys, @QueryParam('startKey') String startKey, @QueryParam('pageSize') int pageSize) {
    List<FooRes> fooResources;
 //check if keys Collection is empty
 if(keys==null||keys.isEmpty()){
    if(startKey==null || startKey.isEmpty()){
      return Response.status(Status.BAD_REQUEST).build();
    }else{
       if(pageSize==null||pageSize.isEmpty()){
          //set default pageSize
          pageSize=10;

          //call your DAO or Repository or Service methods
        fooResources=foosRepo.partialResults(startKey,pageSize);
         ....

        }
   }else{
     fooResources=foosRepo.findByKeys(keys);
   }
 }

 return Response.ok().entity(fooResources).build();
}

This is raw idea you can make your more clear instead of using nested net of if..else..

Comments