REST API 设计中的高级分页、排序和过滤
Posted
技术标签:
【中文标题】REST API 设计中的高级分页、排序和过滤【英文标题】:Advanced paging, sorting and filtering in REST API design 【发布时间】: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", ...) 【参考方案1】:您是否尝试过发布带有过滤器的正文?
"age":
"$gte": 30,
"$lte": 40
,
"status":
"$in": [
"Divorced",
"Single"
]
【讨论】:
这是我正在考虑的解决方案,但我不喜欢它,因为我们使用的是 POST,而我们应该在语义上使用 GET。我更喜欢与通常的 REST“良好实践”没有太大差异的东西...... 如果结合@Adam 建议的解决方案***.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 查询格式。问题又来了,清理用户查询并映射到针对数据库的参数化查询。以上是关于REST API 设计中的高级分页、排序和过滤的主要内容,如果未能解决你的问题,请参考以下文章
drf之组件(认证权限排序过滤分页等)和xadmincoreapi