如何通过在单个REST API调用中过滤父项来正确访问子级

时间:2018-06-15 03:36:25

标签: rest api-design

我重写一个API以更加RESTful,但我在设计问题上苦苦挣扎。我先解释一下情况然后再回答我的问题。

状况:

我有两套资源usersitems。每个user都有一个item列表,因此资源路径会是这样的:

api/v1/users/{userId}/items

此外,每个user都有isPrimary属性,但一次只能有一个用户。这意味着,如果我想获得主要用户,您可以执行以下操作:

api/v1/users?isPrimary=true

这应该返回一个" primary"用户。

我的API客户端想要获取主要用户的项目,但无法进行两次API调用(一次是获取主要用户,第二次是获取用户的项目,使用用户身份)。相反,客户端希望进行单个API调用。

问题:

如果所有客户端都拥有items isPrimary查询参数,我应该如何设计一个只在一次API调用中获取单个用户的user的API?

我的想法:

我想我有一些选择:

选项1)api/v1/users?isPrimary=true将返回项目列表以及用户数据。

我不喜欢这个,因为我有其他API客户端调用api/v1/usersapi/v1/users?isPrimary=true来仅获取和解析用户数据而不是项目数据。用户可以拥有数千个项目,因此每次返回这些项目都会对客户端和服务造成负担。

选项2)api/v1/users/items?isPrimary=true

我也不喜欢这样,因为它很丑陋而且不是真正的RESTful,因为路径中没有{userId}isPrimary不属于{{items 1}}。

选项3)api/v1/users?isPrimary=true&isShowingItems=true

这与第一个类似,但我使用另一个查询参数来标记是否在响应中显示属于该用户的项目。问题是查询参数具有误导性,因为没有与isShowingItems关联的user属性。

非常感谢您提供的任何帮助。提前谢谢。

2 个答案:

答案 0 :(得分:0)

对此没有真正的标准解决方案,我认为您的所有解决方案都是有效的。所以我的答案有点主观。

您是否查看了HAL的API格式? HAL有一种标准方法可以将数据从一个资源嵌入到另一个资源中(使用_embedded),这听起来像是一个非常有效的用例。

服务器可以根据多个条件决定是否嵌入项目,但一个便宜的解决方案可能只是添加查询参数,如?embed=items

即使您不使用HAL,从概念上讲,您仍然可以类似地复制此行为。或者也许你只使用_embedded。至少它重新使用现有的想法来构建新的东西。

除了这个实用的解决方案之外,在多个端点上暴露数据的非RESTful中没有任何内容。因此,如果您创建了如下资源:

/v1/primary-user-with-items

然后,这可能是丑陋的,并且与API的其余部分不一致,但不是固有的 '不是RESTful' (对不起双重否定)。

答案 1 :(得分:0)

您可以包括一个称为fieldsets的List 参数,然后包括如果它们在fieldsets中指定的东西。这样的好处是,您可以通过将字段集添加到API中包含您可能希望包含的字段的任何对象上来重用模式。

api/v1/users?isPrimary=true&fieldsets=items