具有不同数量查询参数的两种 GET 方法:REST

Two GET methods with different number of query parameters : REST

我有一个 Rest 端点 class 如下:

@Path("/sports")
public interface SportsEndpoint {

    @GET
    List<Player> getPlayersOfSports(@QueryParam("sportId") String sportId, @QueryParam("sportName") String sportName);


    @GET
    List<Player> getPlayersOfSports(@QueryParam("sportId") String sportId, @QueryParam("sportName") String sportName, @QueryParam("country") String country);

}

如您所见,我有两个 GET 方法,它们具有几乎相同的签名,除了第二种方法需要一个额外的 QueryParam

我尝试使用 urls 访问这些端点:

http://localhost:8080/rest/api/sports?sportId=100&sportName=badminton http://localhost:8080/rest/api/sports?sportId=100&sportName=badminton&country=japan

这两个 url 都在解析使用第一个方法签名。理想情况下,我期望对于第一个 url,将调用第一个方法签名,对于第二个 url,将调用第二个方法(具有 3 个查询参数的方法)。
但是看起来在这两种情况下都调用了第一种方法。

我知道 Rest 资源是由路径而不是查询参数唯一标识的。但是即使查询参数个数不同,rest端点也不会被唯一标识吗?
有人可以指出一些 specifications/articles/documentation 在设计其余 api 端点时我可以理解多态性吗?

仅供参考:我正在使用 RestEasy。

Java 据我所知,其余 API 是 Jax-Rs 的实现,因此您可以阅读 Jax-Rs specification ,

Jax-Rs 将路径映射到资源方法。资源方法必须具有唯一路径。查询参数不被视为路径的一部分。资源方法是用请求方法指示符注释的资源 class 的方法。当两个方法共享相同的标识符和路径时,规范并没有决定会发生什么,但是大多数实现将只使用其中一个并且不会报告错误。

(符合URL specs。)

这意味着您不能使用重载。

允许继承。来自 Jax-Rs 规范:

JAX-RS annotations MAY be used on the methods and method parameters of a super-class or an implemented interface. Such annotations are inherited by a corresponding sub-class or implementation class method provided that method and its parameters do not have any JAX-RS annotations of its own. Annotations on a super-class take precedence over those on an implemented interface. If a subclass or implementation method has any JAX-RS annotations then all of the annotations on the super class or interface method are ignored. E.g.:

QueryParams 是可选参数,如

you correctly stated I know that Rest resources are uniquely identified by the path and not the query params

并回答你的问题,

yes even though the number of query parameters are different, the rest endpoint will not be uniquely identified ? as it is identified by the path not the query params.

如果您希望根据 querystring 中的输入数量调用您的方法 最好创建一个方法,根据您的要求获取所有 queryparam,并根据提供的输入数量,分别调用每个方法。

所以在你的情况下,它可以重写如下:-

@Path("/sports")
public class SportsEndpoint {
        
    @GET
    List<Player> getPlayers(@QueryParam("sportId") String sportId, 
                            @QueryParam("sportName") String sportName,
                            @QueryParam("country") String country){
        if(sportId != null && sportName != null) {
            getPlayersOfSports(sportId,sportName);
        } else if (sportId != null && sportName != null && country != null) {
            getPlayersOfSports(sportId,sportName,country);
        }
    }
}

then you define the method overloading in your business logic, which will have 2 overloaded methods, which varies based on no of arguments. This way you can achieve polymorphism.