假设我有一个REST资源,如:
/公司/ {companyId} /部门/ {DepartmentID的} /雇员/ {EMPLOYEEID}
和CompanyEntity有List<DepartementEntity>
且DepartmentEntity有List<EmployeeEntity>
的实体类。
所有ID都是唯一的。
所以现在有人打电话了
GET /companies/{companyId}/departments/{departmentId}/employees/{employeeId}
在Spring Data JPA / Hibernate中使用{employeeId}找到员工的好方法是什么?
方式:
employeeRepository.findOne(EMPLOYEEID);
专业版:只需1次查询
Contra:companyId和departmentId未使用。它们甚至可以是随机的。 这是GET / employee / {id},但我希望将嵌套资源与公司和部门保持一致。
此外,我想访问公司对象,以检查询问的人是否与员工在同一家公司。
方式:
company = companyRepository.findOne(companyId);
for(DepartmentEntity department:company.getDepartments()){
if(department.getId() == departmentId) {
for(EmployeeEntity employee : department.getEmployees()) {
if(employee.getId() == employeeId)
return employee;
}
}
}
Pro:companyId和departementId被视为
Contra:如果你使用延迟加载,很多查询
感谢。
答案 0 :(得分:0)
只需阅读问题和评论,几点:
更广泛地考虑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
。无需更高级别的嵌套,因为员工以及您需要了解的有关该部门的所有其他信息都可以通过规范资源获得。