URL矩阵参数与查询参数


178

我想知道是在URL中使用矩阵还是查询参数。我发现对该主题的较早讨论并不令人满意。

例子

乍看之下,矩阵参数似乎只有优点:

  • 更具可读性
  • 不需要对XML文档中的“&”进行编码和解码
  • 带有“?”的网址 在许多情况下不会被缓存;具有矩阵参数的URL被缓存
  • 矩阵参数可以出现在路径的任何地方,并且不限于其结尾
  • 矩阵参数可以具有多个值: paramA=val1,val2

但是也有缺点:

  • 只有少数框架(如JAX-RS)支持矩阵参数
  • 当浏览器通过GET提交表单时,这些参数成为查询参数。因此,对于同一任务,它以两种参数结束。为了不混淆REST服务的用户并限制服务开发人员的工作量,在此区域中使用始终查询参数会更容易。

由于服务的开发人员可以选择支持矩阵参数的框架,因此唯一的缺点是浏览器默认会创建查询参数。

还有其他缺点吗?你会怎么做?


10
我不确定矩阵网址有什么大不了的。根据TBL写的w3c设计文章,这只是一个设计思想,并明确声明它不是网络的功能。使用相对URL之类的东西时不会实现。如果要使用它,那很好。没有标准的使用方式,因为它不是标准。
史蒂夫·波默罗伊

2
@Steve Pomeroy:这是您提到的文章:w3.org/DesignIssues/MatrixURIs.html
Marcel

3
@Marcel:是的。对于那些考虑矩阵URL的人,请注意文档顶部的“状态:个人视图”。
史蒂夫·波默罗伊

矩阵参数可以具有多个值吗?真?
Ayyash

查询参数也可以具有多个值:some.where / thing?paramA = 1&paramA = 6542
EricS

Answers:


215

重要的区别在于,矩阵参数适用于特定的路径元素,而查询参数适用于整个请求。当对多个级别的资源和子资源进行复杂的REST样式查询时,这会起作用:

http://example.com/res/categories;name=foo/objects;name=green/?page=1

这实际上归结为命名空间。

注意:此处的资源“级别”为categoriesobjects

如果仅查询参数用于多级URL,您将最终得到

http://example.com/res?categories_name=foo&objects_name=green&page=1

这样,您还将失去请求中参数局部性所增加的清晰度。此外,当使用类似JAX-RS的框架时,所有查询参数都将显示在每个资源处理程序中,从而导致潜在的冲突和混乱。

如果您的查询只有一个“级别”,则区别并不是很重要,并且两种类型的参数可以有效地互换,但是,查询参数通常得到更好的支持和更广泛的认可。通常,我建议您坚持使用诸如HTML表单和简单的单级HTTP API之类的查询参数。


2
不相关:/?部分代表资源吗?
Jin Kwon

7
?开始请求的查询参数的一部分。与矩阵参数相反,查询参数是URL参数的最常见类型。问号前的斜杠可确保查询参数page不会碰到斜杠之前的矩阵参数。我想如果没有附加任何矩阵参数categories,查询参数就可以这样附加而不使用斜杠:http://example.com/res/categories?page=1
Teemu Leisti

8
确实可以在任何路径段中指定矩阵参数,例如,JAX-RS不会将其与在使用@MatrixParam注入时附加到的路径段相关联。根据“ Restful Java with JAX-RS 2.0”,诸如“ GET / mercedes / e55; color = black / 2006 / interior; color = tan”之类的请求将对颜色矩阵参数进行模糊定义。虽然看起来好像您单独处理每个PathSegment一样,但是您可以弄清楚它的含义……与指定categoryName = foo; objectName = green相比,它很有用,但要花更多的精力。
UFL1138 2014年

16

除了Tim Sylvester的答案,我还要提供一个示例,说明如何使用JAX-RS处理矩阵参数。

  1. 最后一个资源元素的矩阵参数

    http://localhost:8080/res/categories/objects;name=green
    

    您可以使用@MatrixParam注释访问它们

    @GET
    @Path("categories/objects")
    public String objects(@MatrixParam("name") String objectName) {
      return objectName;
    }
    

    响应

    green
    

    但是像Javadoc的状态

    请注意,@MatrixParam注释值是指矩阵参数的名称,该参数位于注入了矩阵参数值的经过路径注释的Java结构的最后一个匹配路径段中。

    ...使我们指向第2点的原因

  2. URL中间的矩阵参数

    http://localhost:8080/res/categories;name=foo/objects;name=green
    

    您可以使用路径变量和随时随地访问矩阵参数@PathParam PathSegment

    @GET
    @Path("{categoryVar:categories}/objects")
    public String objectsByCategory(@PathParam("categoryVar") PathSegment categorySegment, 
                                    @MatrixParam("name") String objectName) {
      MultivaluedMap<String, String> matrixParameters = categorySegment.getMatrixParameters();
      String categorySegmentPath = categorySegment.getPath();
      String string = String.format("object %s, path:%s, matrixParams:%s%n", objectName,
              categorySegmentPath, matrixParameters);
      return string;
    }
    

    响应

    object green, path:categories, matrixParams:[name=foo]
    

    由于矩阵参数是作为a提供的,因此MultivaluedMap您可以通过以下方式访问每个参数

    List<String> names = matrixParameters.get("name");
    

    或者如果您只需要第一个

    String name = matrixParameters.getFirst("name");
    
  3. 将所有矩阵参数作为一种方法参数

    http://localhost:8080/res/categories;name=foo/objects;name=green//attributes;name=size
    

    使用一个List<PathSegment>将它们全部

    @GET
    @Path("all/{var:.+}")
    public String allSegments(@PathParam("var") List<PathSegment> pathSegments) {
      StringBuilder sb =  new StringBuilder();
    
      for (PathSegment pathSegment : pathSegments) {
        sb.append("path: ");
        sb.append(pathSegment.getPath());
        sb.append(", matrix parameters ");
        sb.append(pathSegment.getMatrixParameters());
        sb.append("<br/>");
      }
    
      return sb.toString();
    }
    

    响应

    path: categories, matrix parameters [name=foo]
    path: objects, matrix parameters [name=green]
    path: attributes, matrix parameters [name=size]
    

11

-太重要了,不能降级为评论部分。-

我不确定矩阵网址有什么大不了的。根据TBL写的w3c设计文章,这只是一个设计思想,并明确声明它不是网络的功能。使用相对URL之类的东西时不会实现。如果您想使用它,那很好。没有标准的使用方式,因为它不是标准。–史蒂夫·波默罗伊

简短的回答是,如果出于业务目的需要RS,则最好使用request参数。


5
有人告诉Angular 2开发人员,他们认为他们是如此独特,因此需要实现它!
马特·皮耶吉

2
@MattPileggi我也因为Angular 2而阅读了这篇文章。Angular 2的几乎每个方面都是高度专业化,非常规的,并且与现有的使用模式不符。到目前为止,尚未证明这会增加缓解价值。
阿兰·哈达德

1
伙计们,我也是出于同样的原因在这里,但让我为这个问题提供一些要点,涉及角度2团队github页面上有关url矩阵和google analytis的问题:github.com/angular/angular/issues/11740 但是经过一些研究,URL矩阵表示法似乎比url查询参数更易于理解,主要是当我们需要在中间或url(不仅是结尾)中需要某个参数时
理查德·李

8
我猜每个认为这是非标准的人都不熟悉uri模板规范吗?在路径参数中编码复杂对象是uri模板的一个非常有用的功能。仅仅因为大多数人不了解或使用它并不意味着有角开发人员将无用的复杂性注入您的生活是一种邪恶的阴谋。
Ajax

2
Pffft-“ <我直到现在还不知道的东西>是不规范的,因此保留了我的无知的可接受性”。TBL对某个想法所做的决定或未做出决定的决定在很大程度上并不重要。它不是2001年他的网站的功能。客户端和服务器实现者选择要使用的功能都是网络。如果Angular支持矩阵参数,而JAX-RS支持它们,那么您选择了这些实现工具,然后继续使用可行的方法。
戴夫
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.