如果标题有点令人困惑,请耐心等待,我会尽力解释下面的问题。
说我有以下两个端点
api/companies
(返回以下所有公司的列表)
[{name: "company1", id: 1}, {name: "company2", id: 2}]
api/companies/{companyeId}/employees
(返回特定公司的所有员工列表,如下所示)
[{name: "employee1", id: 1}, {name: "employee2", id: 2}]
客户方需要的是公司清单,每个公司都有一份员工清单。结果应如下所示:
[
{
name: "company1",
id: 1,
employees: [ {name: "employee1", id: 1}, {name: "employee2", id: 2} ]
},
{
name: "company2",
id: 2,
employees: [ {name: "employee3", id: 3}, {name: "employee4", id: 4} ]
},
]
我可以通过两种方式来做到这一点:
api/companies
的最小资源单位是公司而不是员工,所以客户应该发现公司作为可用资源而非雇员。)然后,REST客户端应该能够动态使用服务器提供的链接来发现它需要的所有可用操作和资源
api/companies
返回公司列表。可能会向此端点添加一个名为responseHasEmployees
的查询参数,这是一个布尔默认值为false
,因此当用户通过GET
进行api/companies?responseHasEmployees=true
时,响应正文将会有一个每个公司对象内的员工名单。所以我的问题是,哪种方式是实现客户端目标的更好方法? (不一定必须是上述两个。)
可能有用的额外信息 :公司和员工存储在不同的表中,而员工表的列为company_fk
。
答案 0 :(得分:1)
首先问自己一些问题:
这是一种常见的情况吗? 以这种方式请求数据是否合乎逻辑?
如果是这样,以这种方式提供数据可能是有意义的。
接下来,您是否已经实现了传递变量的api调用? 根据你的HATEOAS原则,你可能不应该这样做。客户不应该知道或理解您网址中的变量值。 如果没有,请远离它。尽可能让客户端保持干净。你可以制作第三个不同的api" api / companiesWithEmployees"这符合您的HATEOAS原则,客户不需要知道关于API的参数或其他工作方式的任何信息,只有他们将获得"有员工的公司"。 而且,成本很低;代码库中的另一种方法。客户端以较低的成本更简单。
接下来考虑一些发展后果: 您是否打开了更具体的API请求的大门? 您是否能够通过API确保您想要访问的数据? 您是否能够维护您的HATEOAS原则,因为客户知道他们需要知道的所有内容?
接下来将这样的场景纳入未来的api设计中: 你可以先发制人地拨打类似的api电话吗?即(客户和订单,您是否只需提供一个api调用,使两者相互关联?)
最终,我对你的问题的回答是继续进行这个新的api通话。设置,测试和维护此特定更改的开销似乎非常小,以这种方式请求数据的可能性似乎很高。
答案 1 :(得分:0)
我假设您构建的客户端将有一个界面来查看公司列表,其中可以选择查看公司员工。所以最好是按需拉动而不是一次加载整个数据。
如果您可以将资源的属性视为子资源,请不要将整个子资源数据添加到主资源API中。您可以包含一个推荐链接,客户端可以使用该链接来获取子资源数据。
在这种情况下,
公司名称,联系电话,地址 - 这些是公司对象的属性,而不是公司的子资源,而员工可以被视为子资源。