Spring MVC中将与API相关的逻辑放在哪里?

时间:2019-08-19 15:28:15

标签: java spring rest spring-boot spring-mvc

在将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,这会给系统增加很多噪音。

有最佳实践吗?

3 个答案:

答案 0 :(得分:1)

API代表应用程序编程接口

因此,它应该仅仅是将其余调用转换为对服务的正确调用的一层。业务逻辑本身应在服务层中实现。

这样思考:如果有一天REST被其他某种技术取代,或者您想添加另一种方法来执行相同的功能(例如,对外部事件做出反应等),则只需实现新的API。由于功能本身是在服务中实现的,因此根本不需要更改。

如果您觉得CRUD服务功能过于肿,仍然可以将其与其他任何功能分开。

如果您确实100%确定REST API仅需要某些功能,则可以在控制器中实现它。但是测试控制器可能会遇到一些挑战,因此除非您解决了该问题,否则我不建议您这样做。

答案 1 :(得分:1)

将业务逻辑保留在“服务”层中,并且仅将特定于委派的代码保留在控制器中。

经验法则:

演示层:控制器(@Controller)

仅负责委派应用服务

应用程序服务层:应用程序服务(@Service)

负责业务用例,任何业务逻辑计算或规则/算法等

存储库(@存储库)等

没有业务逻辑,只有数据库操作

答案 2 :(得分:1)

控制器不应包含任何属于服务层的代码,即业务逻辑。 即使我们以更好的结构方式创建微服务。如果需要,我们可以将CRUD操作放置在一项服务中,而可以将其他操作放置在另一项服务中可能有所不同。

理想之路

  • 对于REST API请求,响应是应由控制器处理的核心部分
  • 服务应包含企业登录名
  • 用于处理数据库操作的存储库
  • 根据要求DTO / DAO

为什么?

  • 结构化方式(更清洁,更易于理解/发现)
  • 易于编写TestCases