根据我的理解,repository
确实有问题,service
执行所有业务逻辑,controller
接收请求。因此,当请求进入时,订单通常为controller
- > service
- > repository
然后将数据传递回客户端。
我现在面临的问题是我的大多数api都涉及多个存储库。例如,获取用户的电子邮件列表的请求。我需要首先解码加密的字符串(在UserService
中完成)。如果成功,请使用从字符串解密的id
来搜索电子邮件(在EmailService
中完成)。在这种情况下,请求首先路由到EmailController
,然后调用EmailService
。我是否应该进行所有解密并在UserRepository
或EmailService
处拨打UserService
来处理所有这些问题?另外,如果我想返回ResponseEntity
,EmailService
是否应该返回电子邮件列表或ResponseEntity
,或EmailController
来构建ResponseEntity
?
答案 0 :(得分:2)
确实有不同的方法但无论如何我认为真的要遵循两条规则。
第一条规则:继续进行的一致性
如果您根据某些条件决定一种或两种方式,最重要的是对任何应用程序用例一致地应用它。
如果您创建了不需要的变体,代码读取和可维护性将成为一场噩梦。
第二条规则:为每个实体/资源设计可重复使用的设计可重复使用并设计功能设计而不是“驴”一对一层设计,因为每种实体/资源不是孤立的。
在这里您可以参考这个用例:
获取用户电子邮件列表的请求
这是一种处理方式
我不是说这是“道路”。这只是我的方式。
1)在其余控制器和服务层之间建立一对一的映射可以简化您的设计:
EmailController
- > EmailService
UserController
- > UserService
但请注意,它有一个警告。
如果在不同的服务类中重复类似的逻辑,则可能意味着应引入多个休息控制器使用的可重用服务。
在这种情况下,您可以拥有控制器,Controller与服务层之间的一对一映射,即:EmailController
与EmailService
通信以及可能使用的多个其他常见服务按EmailController
。
在您的上下文中,这是一个应该引入公共服务的具体示例。
假设这个任务:
“我需要首先解码加密的字符串”
在由不同控制器处理的多个用例中执行,例如EmailController
和UserController
,最好在专用服务中提取处理,而不是在{{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
可以返回分页结果,这是一个可以同时位于Service
和Repository
层的界面。然后在Controller
中将分页结果转换为ResponseEntity
,以响应请求。不要让ResponseEntity
冒险在Controller
之外。