【问题标题】:Where to put API related logic in Spring MVC?在 Spring MVC 中,API 相关的逻辑应该放在哪里?
【发布时间】:2019-08-19 15:28:15
【问题描述】:

当为 REST API 使用 Spring MVC 时,我通常具有普通组件 - 用于数据库访问的存储库、用于 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,这会给系统增加很多噪音。

有最佳实践吗?

【问题讨论】:

  • 我认为使用所谓的service 类是放置所有这些的正确位置。您可以将编排的权重放在该层上,并将 API 留给请求/响应......这是有道理的。我完全明白你在说什么,但从长远来看,有时发出“一些”噪音会更好。
  • 你的问题的答案是MVC设计模式en.wikipedia.org/wiki/Model–view–controller

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


【解决方案1】:

API 代表应用程序编程接口

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

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

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

如果您真的 100% 确定某些功能只需要 REST API,您可以在控制器中实现它。但是测试控制器可能有点挑战,所以除非你解决了这个问题,否则我不建议这样做。

【讨论】:

    【解决方案2】:

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

    经验法则:

    表示层:控制器(@Controller)

    只负责委托给应用服务

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

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

    存储库 (@Repository) 等

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

    【讨论】:

      【解决方案3】:

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

      理想方式

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

      为什么?

      • 结构化方式(更简洁,更易于理解/发现)
      • 易于编写测试用例

      【讨论】:

        最近更新 更多