在将Spring MVC用于REST API时,我通常具有正常的组件-用于数据库访问的存储库,用于CRUD操作的服务以及用于Web层的RESTController。
当我想添加一个不是典型的CRUD API的新API时,事情变得不平衡。例如,假设我有一个Person类
class Person{
private Long id;
private String name;
private List<Person> familyMembers;
private Address address;
private Bank bank;
}
我想添加一个将通过调用使用的api
POST /persons/{personId}/registerToBestBank
该方法将执行各种非常具体的计算,它可能会将其注册到拥有最多家庭成员的银行,或者是最亲近他的银行-或取决于其他实体。
RestController是唯一将使用此计算的位置,因此对我来说,将其放置在该位置,而不是向服务中添加更多API,这会给系统增加很多噪音。
有最佳实践吗?
答案 0 :(得分:1)
API代表应用程序编程接口。
因此,它应该仅仅是将其余调用转换为对服务的正确调用的一层。业务逻辑本身应在服务层中实现。
这样思考:如果有一天REST被其他某种技术取代,或者您想添加另一种方法来执行相同的功能(例如,对外部事件做出反应等),则只需实现新的API。由于功能本身是在服务中实现的,因此根本不需要更改。
如果您觉得CRUD服务功能过于肿,仍然可以将其与其他任何功能分开。
如果您确实100%确定REST API仅需要某些功能,则可以在控制器中实现它。但是测试控制器可能会遇到一些挑战,因此除非您解决了该问题,否则我不建议您这样做。
答案 1 :(得分:1)
将业务逻辑保留在“服务”层中,并且仅将特定于委派的代码保留在控制器中。
经验法则:
演示层:控制器(@Controller)
仅负责委派应用服务
应用程序服务层:应用程序服务(@Service)
负责业务用例,任何业务逻辑计算或规则/算法等
存储库(@存储库)等
没有业务逻辑,只有数据库操作
答案 2 :(得分:1)
控制器不应包含任何属于服务层的代码,即业务逻辑。 即使我们以更好的结构方式创建微服务。如果需要,我们可以将CRUD操作放置在一项服务中,而可以将其他操作放置在另一项服务中可能有所不同。
理想之路
为什么?