我重写一个API以更加RESTful,但我在设计问题上苦苦挣扎。我先解释一下情况然后再回答我的问题。
状况:
我有两套资源users
和items
。每个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/users
或api/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
属性。
非常感谢您提供的任何帮助。提前谢谢。
答案 0 :(得分:0)
对此没有真正的标准解决方案,我认为您的所有解决方案都是有效的。所以我的答案有点主观。
您是否查看了HAL的API格式? HAL有一种标准方法可以将数据从一个资源嵌入到另一个资源中(使用_embedded
),这听起来像是一个非常有效的用例。
服务器可以根据多个条件决定是否嵌入项目,但一个便宜的解决方案可能只是添加查询参数,如?embed=items
即使您不使用HAL,从概念上讲,您仍然可以类似地复制此行为。或者也许你只使用_embedded
。至少它重新使用现有的想法来构建新的东西。
除了这个实用的解决方案之外,在多个端点上暴露数据的非RESTful中没有任何内容。因此,如果您创建了如下资源:
/v1/primary-user-with-items
然后,这可能是丑陋的,并且与API的其余部分不一致,但不是固有的 '不是RESTful' (对不起双重否定)。
答案 1 :(得分:0)
您可以包括一个称为fieldsets的List
api/v1/users?isPrimary=true&fieldsets=items