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

问题描述 投票:2回答:2

根据我的理解,repository确实很糟糕,service完成了所有业务逻辑,controller收到了请求。所以当一个请求进来时,顺序通常是controller - > service - > repository然后将数据传回客户端。

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

java spring rest
2个回答
2
投票

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

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

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

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


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

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

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

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

  • EmailController-> EmailService
  • UserController-> UserService

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

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

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

在由不同控制器处理的多个用例中执行,例如EmailControllerUserController,在专用服务中提取处理要好得多,而不是在EmailServiceUserService中复制它。

所以EmailController会有这些依赖:

- EmailController  -> EmailService
                   -> EncryptingService 

UserController也是如此:

- UserController   ->  UserService
                   ->  EncryptingService

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

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

- UserService  ->  UserRepository                  

或更多依赖项:

- UserService  ->  UserRepository
               ->  EmailRepository

3)关于这最后一个问题

另外,如果我想返回ResponseEntity,EmailService应该返回电子邮件列表还是ResponseEntity,还是让EmailController构建ResponseEntity?

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


1
投票

正如你所说的那样,Services包含业务逻辑,所以他们不应该关心解密,IMO应该隐藏在Repository实现中,这是因为业务逻辑与CRUD逻辑混合导致你的设计问题。

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

© www.soinside.com 2019 - 2024. All rights reserved.