如何使用RESTAPI实现复杂查询?
我正在使用余烬数据构建一个余烬JS应用程序 我的应用程序中的某些功能需要相当复杂的查询 例如,假设我有三个实体——学生、教师和班级。如果我想得到1993年以前出生的所有参加X老师授课的学生的名单,我怎么能用RESTful api做到这一点?在纯SQL中这很容易,但我不确定在API中实现这一点的最佳实践 我是否需要在我的基本RESTAPI旁边构建一个自定义端点 所以我仍然有:如何使用RESTAPI实现复杂查询?,api,rest,ember-data,Api,Rest,Ember Data,我正在使用余烬数据构建一个余烬JS应用程序 我的应用程序中的某些功能需要相当复杂的查询 例如,假设我有三个实体——学生、教师和班级。如果我想得到1993年以前出生的所有参加X老师授课的学生的名单,我怎么能用RESTful api做到这一点?在纯SQL中这很容易,但我不确定在API中实现这一点的最佳实践 我是否需要在我的基本RESTAPI旁边构建一个自定义端点 所以我仍然有: GET /students (which returns all the students) GET /students/
GET /students (which returns all the students)
GET /students/{id} (which returns a specific student)
etc
然后为我的“自定义”查询实现以下功能:
GET /students/custom/born_before/{date}/taught_by/{teacher_id}
或者有没有更标准化的方法来实现这一点?您可以改变您的
GET /students/custom/born_before/{date}/taught_by/{teacher_id}
进入
这只是一个选项:您可以使用提供的字段填充模型实例,并使用它们进行查询。字段越少,搜索范围越广,显示的结果越多
例如,这就是一种方法。一种选择是在学生身上设置一个搜索端点,您可以发布到该端点 所以你可能有:
POST /students/filter
您要发布的筛选器对象看起来类似于:
{ BornBefore:1993, TaughtBy:123 }
我还看到了一个选项,API没有发布,而是使用了一个过滤器,然后使用了一个查询字符串
我自己更喜欢第一个。特别是如果它可能是一个长时间运行的过程,因为您的POST可能会返回一个ID和/或一个指向客户端用于获取状态更新和结果的API调用的rel
链接
因此,您将发布/Students/filter
,它将以/Students/filter/123
的rel回复,您的客户机将在/Students/filter/123
上定期执行获取
,直到获得结果对象。当然,对于简单、简短的查询,您可以立即返回结果。但是如果要花一两秒钟以上的时间,你可以走这条路
有一些关于构建ReSTful API的好信息。我不喜欢使用POST来“获取”信息,我认为这不是ReSTful。我更新了我的答案,以说明在某些情况下为什么要发布POST。本质上,您是在发布服务器运行的搜索对象,然后稍后再获取结果。很像你将一个图像发布到服务器上,然后再检索它。这更像是
/students/filters
,因为有很多。无论如何,对于一般用例来说,这不是一个最佳的解决方案。必须发出两个请求才能执行简单的搜索&将其存储在后端没有什么意义。使用GET的最大问题是,代理将使用它们自己的规则缓存它们,尽管您可能发送任何头。POST/PUT从不缓存。尽管这种情况很少见,但在与用户打交道时(尤其是在业务环境中)仍然需要考虑。这是一种更标准、更实用的解决方案,结果可以缓存(与POST
的解决方案相反)。@Aurélien这也可能是不幸的,尤其是如果你不想缓存。我唯一的问题是,对于复杂的查询和过滤器,这样做真的很难看。@Rahly首先,您没有义务实现缓存。其次,缓存并不意味着获取过时的数据(例如,ETag
就是一种很好的处理方法)。如果实现正确,这只意味着你不必再计算你已经计算过的东西。@Aurélien不,这就是问题所在,其他人可以在你和你的用户控制之外实现缓存。我在实际的代理环境中见过,代理服务器忽略所有缓存头并执行自己的“规则”。POST是常用的非缓存方法
{ BornBefore:1993, TaughtBy:123 }