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.
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 it more redable some list of params to method call mapping