寻找嵌套资源的练习
Posted
技术标签:
【中文标题】寻找嵌套资源的练习【英文标题】:Practice for finding a nested resource 【发布时间】:2017-04-25 23:07:27 【问题描述】:假设我有一个 REST 资源,例如:
/companies/companyId/departments/departmentId/employees/employeeId
CompanyEntity 具有List<DepartementEntity>
和 DepartmentEntity 具有List<EmployeeEntity>
的实体类。
所有 ID 都是唯一的。
所以现在有人打电话
GET /companies/companyId/departments/departmentId/employees/employeeId
在 Spring Data JPA / Hibernate 中找到具有 employeeId 的员工的好方法是什么?
方式:
employeeRepository.findOne(employeeId);
专业版:只需 1 次查询
相反:companyId 和 departmentId 未使用。它们甚至可以是随机的。 这是相当 GET /employee/id 但我想保留公司和部门的嵌套资源。
我还想访问公司对象以检查询问的人是否与员工在同一家公司。
方式:
公司 = companyRepository.findOne(companyId);
for(DepartmentEntity 部门: company.getDepartments())
if(department.getId() == departmentId)
for(EmployeeEntity employee : department.getEmployees())
if(employee.getId() == employeeId)
return employee;
Pro:companyId 和departementId 被考虑
相反:如果您使用延迟加载,则会有很多查询
谢谢。
【问题讨论】:
if (employee.getDepartment().getId() != departmentId || employee.getDepartment().getCompany().getId() != companyId) throw ...
怎么样
目前我没有这些从员工到部门和部门到公司的反向引用。但也许是时候整合它们了。谢谢你的意见。
不,尽可能避免双向关联,从长远来看,它们通常会造成麻烦,因为模糊了 API 空间并且众所周知难以正确处理。此外,永远不要让 URI 结构支配您的代码。如果他们的员工标识符是全球唯一的,你为什么要让客户很难找到一个(它需要提供所有那些明显不必要的细节)?
奥利弗,谢谢。我只想在查询人和目标员工在同一公司时才提供员工信息。所以找到目标很简单:employeeRepository.findOne(employeeId)。但是有什么好方法可以检查公司是否相同?请注意,公司和员工之间有部门,没有双向引用。我以为我可以在 URI 中使用公司 ID。
【参考方案1】:
只是阅读问题和cmets,几点:
更广泛地考虑JB Nizet 的建议,我认为这个想法是使用最直接的可用查找,然后进行验证。验证可保护您的数据免受未经授权的访问,并确保关系查询语义保持不变。即,如果员工记录不在指定部门,用户不会期望返回该员工记录;如果部门在指定公司内无效。 因此,提供一种简单的方法来获取员工的部门和部门的公司是有意义的(在您的实现中,不一定在 API 中),因此您可以执行这些验证。或者,每个容器都可以有一个包含 ID 的散列集合,因此您可以轻松确定给定的员工 ID 是否在 department.employees 集合中,并且与 company.departments 中的部门相同。
拥有这样的嵌套集合并不罕见,而且通常很有帮助。 Relational Endpoints 是此 API 设计模式的一个名称。但我同意Oliver Gierke 的观点,即您应该为用户提供通往已知实体的直接路径。将其纳入设计的不同方法:
您可以保留嵌套资源,并添加规范的/departments
和/employees
集合。在从嵌套资源返回的结果中,您可以包含规范链接,如 the pattern suggests。所以GET /companies/123/departments/456/employees/789
可以返回一个员工的表示,以及一个canonical
链接(在标题或正文中,取决于您的电汇格式)到/employees/789
,客户端可以使用它来后续访问员工记录。
更进一步,您可以决定只支持一层嵌套。所以GET /companies/companyId/departments
返回公司内部部门的超链接集合;其中每个超链接都指向规范 URL,例如/departments/456
。无需进一步嵌套,因为员工以及您需要了解的有关部门的所有其他信息都可以通过规范资源获得。
【讨论】:
以上是关于寻找嵌套资源的练习的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 REST kit for Objective-C 请求嵌套资源