【发布时间】:2020-12-12 03:56:27
【问题描述】:
如何为资源集合设计REST url,通过不等于给定值的属性过滤资源?
例如,要获得 8 年级的学生,我们使用
GET /students?grade=8
如果我们需要让学生不进入 8 年级,该怎么做?以及如何设计小于 (<) 、大于 (>) 等?
【问题讨论】:
-
但是,它更多地谈到了分页
如何为资源集合设计REST url,通过不等于给定值的属性过滤资源?
例如,要获得 8 年级的学生,我们使用
GET /students?grade=8
如果我们需要让学生不进入 8 年级,该怎么做?以及如何设计小于 (<) 、大于 (>) 等?
【问题讨论】:
我想做的是将运算符作为参数的一部分,与值分隔。我还将定义非符号运算符以避免需要丑陋的 URL 编码或与参数名称后的等号混淆。对于您的示例,对于非 8 年级的学生来说,这将是这样的:
GET /students?grade=neq|8
8 年级以上的学生将是:
GET /students?grade=gt|8
8 至 10 年级(含)之间的学生:
GET /students?grade=gte|8,lte|10
这种方法可以扩展到其他可过滤的字段,而无需添加额外的参数来修改每个字段的过滤方式。
【讨论】:
Stripe 拥有最受推崇的 API 之一。
他们为每个用点分隔的运算符使用单独的参数。
例如,搜索创建日期:
/charges?created.gt=
/charges?created.gte=
/charges?created.lt=
/charges?created.lte=
在您的情况下,您可以执行以下操作:
/students?grade.gt=8&grade.lt=8
甚至为 not 添加另一个运算符:
/students?grade.not=8
【讨论】:
一种选择是添加一个额外的查询参数,例如gradeOperator,您可以在其中传递要在将值与grade 参数进行比较时使用的运算符。例如,
GET /students?grade=8&gradeOperator=!%3D
!%3D 是!= 的URL-encoded 形式,因此您的REST API 将对运算符进行解编码并将其解释为grade != 8。
另一种方法是在 HTTP 请求正文中传递值和运算符。这样的事情可能会起作用(以 JSON 中提供的正文为例):
GET /students
Content-Type: application/json
{ "grade": {"value": 8, "operator": "!=" } }
这可能很好,因为您不必在gradeOperator 中重复“等级”一词,该运算符只是嵌套在 JSON 对象中作为grade 的值。
在任一解决方案中,您都可以定义任意数量的运算符,包括 <、>、>=、<= 等。请务必正确清理您的 API 接收到的任何输入运算符,尤其是在在数据库查询中使用,以避免SQL injection 攻击。
【讨论】: