【问题标题】:How to handle authentication to adapters on a Hexagonal Architecture如何在六角架构上处理对适配器的身份验证
【发布时间】:2022-07-07 01:09:19
【问题描述】:
我正在使用六边形架构构建一个工作应用程序,并且我有一个名为 CompanySetup 的实体(在核心层中)。当我的系统收到请求时,我会调用调用 CompanySetupRepository(在核心层中定义的接口)的业务服务。在适配器层中,我定义了 CompanySetupRepository,它调用设置微服务来获取设置并返回给调用者(它是一个外部数据存储库)。我的问题是设置微服务需要身份验证来生成令牌,我决定将身份验证放在我的存储库实现(适配器层)的每个方法中。但是,由于我使用的是控制反转,我应该将 SetupAuthentication - 接口 - 放在核心层还是适配器层?
我在使用加密代码时遇到了同样的问题,它应该放在哪里?在核心层还是适配器层?
【问题讨论】:
标签:
domain-driven-design
hexagonal-architecture
【解决方案1】:
六边形架构中没有“核心层”。 HA 在应用程序中定义了 3 层:
- 应用领域层包含您业务的对象模型:
CompanySetup
- 端口层包含所有对外服务的接口:
ICompanySetupRepository
- 适配器层包含端口的所有实现:
CompanySetupRepository
但是,重要的部分是适配器不应被视为应用程序的同质层。每个端口都定义了适配器实现的“范围”。一个适配器可以实现一个或多个端口,但它不应该直接引用另一个适配器的代码。如果它需要一个外部服务,它应该引用适配器的端口,让依赖注入库来完成这项工作。
重新表述您的问题,ICompanySetupAuthentication 和 ICompanySetupEncryption 接口应该放在哪里?这个问题有两种可能的答案。
如果这两个接口的实现特定于 CompanySetup 适配器,并且不应被其他适配器引用,那么您可以将它们放在 CompanySetup 适配器中,具有内部/包范围。您可以在适配器中使用 DI,以便将适配器代码拆分为更小、更易于维护的代码。
如果你想与其他适配器复用代码,那么将接口放在端口层,让每个接口实现都是一个适配器。适配器不能相互引用代码,因此CompanySetupRepository 必须引用ICompanySetupAuthentication 端口。 DI 将在运行时完成其余的工作。
您还可以将该功能一分为二,一个是通用的“加密”端口/适配器,另一个是包含特定加密代码的“公司设置”端口/适配器。特定代码将确定要加密/解密对象的哪些属性,通过其端口将实际加密推迟到另一个适配器。通过这种方式,您可以更改整个应用程序的加密算法(例如从 RSA 到 AES),而无需完全重写如何加密/解密 CompanySetup。