在春天运营回购/服务/控制器的正确/优先方式是什么?

时间:2018-01-11 22:20:06

标签: java spring rest

根据我的理解,repository确实有问题,service执行所有业务逻辑,controller接收请求。因此,当请求进入时,订单通常为controller - > service - > repository然后将数据传递回客户端。

我现在面临的问题是我的大多数api都涉及多个存储库。例如,获取用户的电子邮件列表的请求。我需要首先解码加密的字符串(在UserService中完成)。如果成功,请使用从字符串解密的id来搜索电子邮件(在EmailService中完成)。在这种情况下,请求首先路由到EmailController,然后调用EmailService。我是否应该进行所有解密并在UserRepositoryEmailService处拨打UserService来处理所有这些问题?另外,如果我想返回ResponseEntityEmailService是否应该返回电子邮件列表或ResponseEntity,或EmailController来构建ResponseEntity

2 个答案:

答案 0 :(得分:2)

确实有不同的方法但无论如何我认为真的要遵循两条规则。

第一条规则:继续进行的一致性 如果您根据某些条件决定一种或两种方式,最重要的是对任何应用程序用例一致地应用它。

如果您创建了不需要的变体,代码读取和可维护性将成为一场噩梦。

第二条规则:为每个实体/资源设计可重复使用的设计可重复使用并设计功能设计而不是“驴”一对一层设计,因为每种实体/资源不是孤立的。

在这里您可以参考这个用例:

  

获取用户电子邮件列表的请求

这是一种处理方式 我不是说这是“道路”。这只是我的方式。

1)在其余控制器和服务层之间建立一对一的映射可以简化您的设计:

  • EmailController - > EmailService
  • UserController - > UserService

但请注意,它有一个警告。
如果在不同的服务类中重复类似的逻辑,则可能意味着应引入多个休息控制器使用的可重用服务。
在这种情况下,您可以拥有控制器,Controller与服务层之间的一对一映射,即:EmailControllerEmailService通信以及可能使用的多个其他常见服务按EmailController

在您的上下文中,这是一个应该引入公共服务的具体示例。
假设这个任务:

  

“我需要首先解码加密的字符串”

在由不同控制器处理的多个用例中执行,例如EmailControllerUserController,最好在专用服务中提取处理,而不是在{{1}中复制它}和EmailService

所以UserService会有这些依赖关系:

- EmailController  -> EmailService
                   -> EncryptingService 

同样适用于EmailController

- UserController   ->  UserService
                   ->  EncryptingService

2)服务的设计并不总是与存储库层进行一对一的映射 存储库确实设计为可由任何需要它们完成任务的服务重用 因此,UserController当然必须与UserService进行沟通 但是,如果UserRepository还需要检索一些与UserService实体没有直接关联的电子邮件实体作为实体关系,User必须与UserService进行交互才能完成此任务

因此,根据您的需求,您可以在EmailRepository中将一对一映射作为依赖关系:

- UserService  ->  UserRepository                  

或更多依赖项:

- UserService  ->  UserRepository
               ->  EmailRepository

3)关于最后一个问题

  

另外,如果我想返回ResponseEntity,EmailService应该返回一个   电子邮件列表或ResponseEntity,或者要构建EmailController   ResponseEntity?

不要混淆责任,否则图层会失去价值 服务执行/返回功能性的东西,必须设计成以这种方式工作 UserService包装必须在处理HTTP响应的层中执行,因此仅在Rest控制器中执行。

答案 1 :(得分:1)

正如您已正确说明Services包含业务逻辑所以他们不应该关注解密,IMO应该隐藏在Repository实施中,而这正是'导致您的设计问题,业务逻辑与CRUD逻辑混合。

Repositories可以返回分页结果,这是一个可以同时位于ServiceRepository层的界面。然后在Controller中将分页结果转换为ResponseEntity,以响应请求。不要让ResponseEntity冒险在Controller之外。