RESTful API排序困境

Jul*_*hev 6 architecture sorting rest

我有REST API实现遵循以下原则:休息只返回基本文档,并在那些文档中引用如何获取其他东西等

例如,/ car/5会给我模型:blabla,user_id:1然后如果你需要拥有者你将获得/ user/1来获取用户数据..

这样就可以避免在DB中使用JOINS和东西.所有东西都在它们之间连接,并且在休息客户端部分上相互连接的数据 - 保持简单易于缓存/删除缓存,扩展等.

但是当你需要排序时会发生什么?

想象一下,我们在前端有一些视图来显示以下数据:汽车模型,用户名等......你想按用户名排序,例如.

您无法真正告诉/ car/5按用户名排序,因为它只知道用户ID ...

我看到的一个选项是从用户/用户/列表中排序?sortby = username,然后互连其中哪些返回的ID实际上是指汽车.但这意味着我们需要获得所有用户......并且只使用那些看似杀手性能瓶颈的部分.

谢谢你的任何指示

Row*_*haw 5

我认为你试图避免加入所有错误的原因,因为采用这种方法,你将不得不服务更多的请求.

如果您改回了所有显示的信息(即加入数据库端),那么客户端将不得不减少查询次数,您可以进行排序而无需(懒惰)加载所有子项对象.

另一种选择是将子对象作为子XML元素返回(与OpenStreetMap的RESTful接口的工作方式类似).您仍然可以从客户端获得一次命中,并且您应该能够优化查询以最小化数据库上的负载.


Jac*_*yan 5

如果您要避免服务器中的所有连接并将其留给客户端,那么在这种情况下,您也必须将排序留给客户端。这是因为必须进行连接才能按用户名对汽车进行排序。

您可以创建另一个名为 CarsAndOwners 或类似资源的资源,它返回连接列表,此时在服务器上进行排序变得合理。


And*_*rew 5

首先,您的示例/car/5应该是资源的复数版本,以便实现 RESTful:

/cars/5
/users/1
Run Code Online (Sandbox Code Playgroud)

现在,一般来说,如果您想要一种 RESTful 方法来排序,您可以这样做:

/cars?sort=make&order=asc
Run Code Online (Sandbox Code Playgroud)

在您的示例中,您提到您想按用户名对汽车进行排序。然而,就像你提到的,该cars集合应该对users. 那么,如果您想显示汽车列表并按用户对它们进行分组,您该怎么办?您需要一种方法来检索此信息。执行此操作的一种方法是循环用户并请求与每个用户关联的汽车:

# pseudo code

users.each do |user|
  # assuming the user id is 5,
  # to display the user's cars, 
  # we need to request /users/5/cars
end
Run Code Online (Sandbox Code Playgroud)

因此,我们可以通过类似 的 URL 请求每个人的汽车列表/users/5/cars。这称为嵌套资源。我们仅请求与用户 5 相关的汽车。

但是,您可能会遇到向 API 发出大量请求的问题(这可能没问题,具体取决于您的用例)。

另一种可能更好的方法是在一个请求中执行此操作:

/users/cars?sort=username&order=asc
Run Code Online (Sandbox Code Playgroud)

这将返回一组用户及其按用户名订购的汽车。

另一种方法可能是:

/users?include=[cars]&sort=username&order=asc
Run Code Online (Sandbox Code Playgroud)

但我不像以前那样喜欢这种方法。我会推荐以前的方法/users/cars

旁注:您的列表应该分页,这样当您仅显示部分列表时,就不会产生请求所有列表的开销。users

/users?page=1&per_page=50
Run Code Online (Sandbox Code Playgroud)