【问题标题】:Advanced paging, sorting and filtering in REST API designREST API 设计中的高级分页、排序和过滤
【发布时间】:2017-08-11 02:57:23
【问题描述】:

在 REST API 中,使用 URI 查询参数处理集合的排序、过滤和分页被认为是一种很好的做法,例如:

GET /employees?offset=30&limit=15&name=Mary&sort=-surname

不幸的是,在某些“高级”情况下,参数数量可能会“爆炸”,因此这种解决方案不再可行。

回到前面的例子,假设我们想对许多其他字段应用一些更复杂的过滤器(例如:地址包含“NY”,年龄 > 30,年龄 =100000 美元),以及许多其他...)。

显然,在这种情况下,一组简单的查询参数是不合适的。

这样的情况应该怎么设计?也许客户端应该发送一个包含一些代表查询的结构化数据的 POST?关于如何设计此类查询,是否存在或多或少的标准协议?

谢谢!

【问题讨论】:

  • 你能定义“高级”案例吗?一般来说,你应该能够量化参数,所以参数的数量不会“爆炸”。
  • 将子句与布尔运算符组合(如示例中所示)可能会导致过滤器非常大。另一个在查询中需要大量数据的基本示例可能是“in”运算符,例如:name is in ("Mary", "Jhon", "Carl", ...)

标签: rest


【解决方案1】:

您是否尝试过发布带有过滤器的正文?

{
  "age": {
    "$gte": 30,
    "$lte": 40
  },
  "status": {
    "$in": [
        "Divorced",
        "Single"
    ]
  }
}

【讨论】:

  • 这是我正在考虑的解决方案,但我不喜欢它,因为我们使用的是 POST,而我们应该在语义上使用 GET。我更喜欢与通常的 REST“良好实践”没有太大差异的东西......
  • 如果结合@Adam 建议的解决方案stackoverflow.com/a/42893377/1288109,这个解决方案是可以的:想法是不在资源本身上使用POST,而是创建一个新的“过滤器”实体。发布/员工/过滤器
【解决方案2】:

一种方法是让搜索过滤器成为 REST 资源,这意味着创建新的 REST 方法:

  • POST /filters,期待带有过滤器的主体,例如(marital status is "married" AND salary<100000USD) OR (marital status is "divorced" AND salary>=100000USD) 并返回此搜索的唯一 ID,以及(为了避免往返服务器)第一个结果,以及指向下一个结果的链接
  • GET /filters/<id>/<offset>,返回搜索结果id,从offset开始

【讨论】:

  • 太棒了!这会将集合的过滤转换为过滤器的创建。我喜欢它,因为 POST 动词有效地用于创建新资源(过滤器!),然后 GET 动词随后用于获取其属性(过滤器的结果)。看起来不错!
  • 是的,完全正确。过滤器成为您应用程序的一等公民。您的应用程序可以使用它们来例如向用户展示“您的最后一次搜索”。
  • 问题在于难以实施和昂贵的使用。为此,您基本上需要一个自定义解析器。它称为 RQL。我不确定为什么它没有被广泛采用。也许是因为你离写sql太近了。我不确定使用查询语言过于接近 sql 之类的东西是否好。在某些时候,您最好直接使用 sql 或其他一些查询语言,例如 mongo 查询格式。问题又来了,清理用户查询并映射到针对数据库的参数化查询。
猜你喜欢
  • 2018-01-13
  • 1970-01-01
  • 1970-01-01
  • 2012-09-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-02-19
相关资源
最近更新 更多