【问题标题】:How to implement complex queries with a REST api?如何使用 REST api 实现复杂的查询?
【发布时间】:2018-09-05 15:08:56
【问题描述】:

我正在使用 ember-data 构建一个 EmberJS 应用程序。

我的应用中的某些功能需要相当复杂的查询。

例如,假设我有三个实体 - 学生、教师和班级。如果我想获取 1993 年之前出生的所有学生的列表,这些学生正在上 X 老师教授的课程,我该如何使用 RESTful api 来做到这一点?在普通 SQL 中,这很容易,但我不确定在我的 API 中实现这一点的最佳实践。

我是否需要在我的基本 REST api 旁边构建自定义端点?

所以我还是有:

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}

或者有更标准化的方法吗?

【问题讨论】:

    标签: api rest ember-data


    【解决方案1】:

    你可以改变你的

    GET /students/custom/born_before/{date}/taught_by/{teacher_id}
    

    进入

    GET /students/?born_before={date}&taught_by={teacher_id}
    

    这只是一个"query by example" 选项:您可以使用提供的字段填充模型实例并使用它们进行查询。字段越少,搜索范围越广,要显示的结果也越多。

    例如JIRA's API works就是这样。

    【讨论】:

    • 这是一个更标准、更实用的解决方案
    • 并且可以缓存结果(与POST的方案相反)。
    • @Aurélien 这也可能很不幸,尤其是如果您不想缓存。我唯一的问题是,对于复杂的查询和过滤器,这样做真的很难看。
    • @Rahly 首先,您没有义务实现缓存。其次,缓存并不意味着获取过时的数据(例如ETag 是处理此问题的好方法)。如果实施得当,这意味着您不必再次计算您已经计算过的内容。
    • @Aurélien 不,这就是问题所在,其他人可以在您和您的用户控制之外实现缓存。我在实际代理环境中看到代理服务器忽略所有缓存标头并执行自己的“规则”。 POST 是常用的非缓存方法
    【解决方案2】:

    一种选择是在您的学生身上设置一个搜索端点,您可以将其发布到该端点。

    所以你可能有:

    POST /students/filter
    

    您要发布的过滤器对象如下所示:

    { BornBefore:1993, TaughtBy:123 }
    

    我还看到了一个选项,API 有一个过滤器,而不是发布它,然后使用查询字符串。

    我自己更喜欢第一个。特别是如果它可能是一个长时间运行的过程,因为您的 POST 可能会返回一个 ID 和/或一个 rel 链接到 API 调用,客户端应该使用该 API 调用来获取状态更新并获得结果。

    那么你会POST /Students/filter,它会回复/Students/Filter/123的rel,你的客户会定期在/Students/Filter/123上执行GET,直到它得到结果对象。当然,对于简单、简短的查询,您可以立即返回结果。但如果需要一两秒以上的时间,你可以走这条路。

    This book by O'Reilly 提供了一些关于构建 ReSTful API 的好信息。

    【讨论】:

    • 我不喜欢使用 POST 来“获取”信息,在我看来这不是 RESTful。
    • 我更新了我的答案,以说明为什么您会在某些情况下发帖。本质上,您是在发布服务器运行的搜索对象,然后稍后获取结果。就像您将图像发布到服务器并稍后检索它一样。
    • 那会更像/students/filters - 因为有很多。无论如何,这不是一般用例的最佳解决方案。必须发出两个请求来进行简单的搜索并将其存储在后端是没有意义的。
    • 我使用 GET 的最大问题是代理将使用他们的 OWN 规则缓存它们,尽管您可以发送任何标头。 POST/PUT 永远不会被缓存。虽然这种情况很少见,但在与用户打交道时仍然是一个问题,尤其是在商业环境中。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-01-03
    • 1970-01-01
    • 2018-12-03
    • 1970-01-01
    • 2019-07-01
    • 2016-10-26
    • 1970-01-01
    相关资源
    最近更新 更多