使用不同的 QueryParams 重载 REST 端点

erp*_*erp 3 java rest jax-rs jersey

我正在尝试确定与变量为 的 Jersey 客户端端点交互的最佳方式Collection<String>。我不是 100% 确定这样做是正确的,但我想知道这是否可能/实现这一目标的正确方法是什么 - 也许@POST带有消息正文?

我的方法DAOSet<Foo> retrieveByKeys(Collection<String> keys). 因此,我试图找出为此创建端点的最佳方法。第一个想法是:

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

或者:

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

我不太确定您是否可以执行第二个操作,但有人建议将其作为可能的解决方案。

无论哪种方式都很好,但同时我的另一种方法DAOList<Foo> retrievePageStartingFrom(String startKey, int pageSize). 我知道在可能的情况下重用 url 是最佳的休息实践,这就是我试图用这两个做的。我只是在努力寻找一种方法来区分这两种方法,但要保持相同的 url。

我想知道是否有可能用其他方式重载端点,@QueryParams但这次是:

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

并且 Jersey 客户端会知道区分这两个调用,因为第一个方法有一个参数,第二个方法有两个也是不同类型的参数。

我想我想我想要做的最好的方法是在 java 中,当你可以有一个带有某些参数的构造函数,另一个带有不同/不同类型参数但方法名称相同的构造函数(显然)。

无论正确答案是什么,如果可能,我都试图为这两种方法保留相同的 URL,我想知道实现这一目标的最佳方法是什么!谢谢。

AsS*_*iDe 5

不,如果所有端点方法都使用相同的 HTTP 方法(例如,都使用 @Get 注释)但查询参数不同,则不可能重载它们。其余资源由 URI 而非参数唯一标识。

您需要做的是检查是否存在不同的查询参数并调用所需的实现:

@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();
}
Run Code Online (Sandbox Code Playgroud)

这是一个原始的想法,你可以让你更清楚,而不是使用 if..else.. 的嵌套网络。