无服务器架构层和 DDD(第 3 部分)- 领域层
无服务器架构层和 DDD(第 3 部分)- 领域层
详细讨论 5 个无服务器架构层,这一次将在第 3 部分中介绍域层。
内容
⚪ 第 1 部分 — 体验层
⚪ 第 2 部分 — 横切层
✔️ **第 3 部分 — 领域层
** ⚪ 第 4 部分 — 数据层
⚪ 第 5 部分 — 平台层
我们将在第 3 部分中介绍的内容:
✔️介绍。
✔️ 快速回顾。
✔️ 什么是无服务器领域驱动设计。
✔️ 领域层。
✔️ 技术考虑和深入研究。
介绍
在本文中,我们将深入探讨 领域层 这是五个中的第三层 无服务架构层 企业组织,所有这些都基于领域驱动设计(DDD)。
在我们走得更远之前 — 请在 LinkedIn 上与我联系以获取未来的博客文章和无服务器新闻 https://www.linkedin.com/in/lee-james-gilmore/
快速回顾
下面是这五种的概述 无服务器架构层 在以下文章中进行了讨论:
[
无服务器架构层
我认为企业组织应该如何以及为什么应该使用具有五种无服务器架构的域驱动设计……
levelup.gitconnected.com
](https://levelup.gitconnected.com/serverless-architecture-layers-a9dc50e9b342)
在下一节中,我们将介绍什么 DDD 是无服务器的,为什么它对 领域层 .
什么是 Serverless 中的域驱动设计?
如果您很高兴您详细了解了 DDD,那么您可以转到下一部分
以下文章涵盖领域驱动设计( DDD ) 使用无服务器,并且是本文的先决条件:
[
无服务器域驱动设计
将 DDD 概念与现实世界的示例分解为有形的无服务器等价物。
leejamesgilmore.medium.com
](/serverless-domain-driven-design-6da44e151cfa)
领域层
在我看来,领域层是最重要的正确和关注( 毕竟这就是您的业务运作方式 )。在 DDD 中,Eric Evans 将其描述为:
“ 负责表示业务的概念、有关业务情况的信息和业务规则。 ”
从一个 无服务器架构层 从角度来看,这允许我们所有的业务逻辑正确地封装到子域中( 域服务 ),并通过我们的许多 经验 在里面 体验层 ( 如下所示 ):
Example of many experiences utilising the domain logic from the Domain Layer
这可以防止在企业组织中通常发生的情况,其中业务逻辑在许多解决方案和层之间重复和泄漏,并且数据库和内部结构在全球范围内共享,如下所示:
Example of duplicated business logic leaking through an organisation, and services going directly to databases they don’t own
DDD 中的“域服务”是什么?
当涉及到 无服务器架构层 我们需要考虑 领域层 与领域驱动设计(DDD)一起。
领域层由我们的许多 域服务 ,代表整个业务的子域、域模型和通用语言。这些域服务可以被我们的 体验层 ( 在本系列的第 1 部分中讨论 )。
一个 领域 是应用软件的主题领域,例如整个电子商务领域。当我们将其进一步拆分为子域时,我们发现我们有子域,例如订单、付款、客户等
一个 子域 本质上是基于其封装的业务能力的整个域的逻辑分离部分,它本身就是一个域。下面我们可以看到 Customer 的子域,它是一个域服务。
我们的域服务的逻辑视图 顾客
如下图所示:
Domain Service for the Customer Domain (Logical View)
我们可以看到这 客户域服务 由多个微服务组成( 聚集体 ) 在定义良好的版本化 REST API 之后。
这种模式确保我们不会构建单体或分布式单体,如下图所示:
We want to ensure that our Domain Services are correctly sized
在 AWS 无服务器世界中,这 顾客 域服务 可能等同于以下内容:
Domain Service for the Customer Domain (AWS view)
我们可以看到 客户域服务 是
✔️ 通过使用 VPC、权限和网络在其自己的 AWS 账户中建立物理有界上下文,这意味着其业务逻辑被正确封装在其接口后面。此限界上下文中的所有微服务都可以在内部相互通信( 可能是 SQS、SNS 或使用 EventBridge 的内部事件总线 )。
✔️ 与此域服务交互的唯一方法是通过定义明确的版本化 API,使用 私有 API 网关 和 IAM 身份验证 ( 这将在文章中进一步详细讨论 )。这意味着进出此域服务的所有流量都在 AWS 骨干网络 通过 私人链接 ( 没有公共访问权限 ),大大减少了不良行为者的攻击面。 ( 领域服务只能由其他领域服务或体验访问 )
✔️ 其他域可以监听内部微服务( 聚集体 ) 域内正在提升到共享企业事件总线 ( 亚马逊事件桥 )。相反,域也可以监听来自其他域的事件。
如果我们从这里缩小 客户域服务 进入我们的整体无服务器架构层,我们可以看到它在概念上的位置( 红色的 ):
The Orders Domain Service in the Overall Serverless Architecture Layers
我们可以看到 订单域 在上面的红色中,与构成整体的其他域服务一起 领域层 ( 库存、采购、销售、用户等 )。
“ 负责表示业务的概念、有关业务情况的信息和业务规则。 ”——埃里克·埃文斯
在一个组织中,这意味着我们可以让独立的自治团队在他们自己的专用 AWS 账户中处理这些域:
Organisational domain engineering teams, each working directly with business stakeholders and SMEs
现在让我们深入研究这些模式,并看看技术方面的考虑。
技术考虑和深入了解
好的,所以我们已经介绍了一些高级域概念和思维过程,并了解域在整个问题空间中的位置;所以现在让我们讨论一些技术方面的考虑。
✔️ 私有域服务
我们希望保护和集中我们的私有域服务,以便仅使用 AWS 网络上的最低权限访问它们。
我们可以看到私有域服务如何与下面的体验层 BFF 一起工作的逻辑视图:
Example of how the Experience Layer and Domain Layers work hand in hand together
然后我们可以放大,从一个 经验 打电话给私人 域服务 使用下面的 IAM 身份验证:
Example of one Experience calling through to a Domain Service
这通过以下方式起作用:
- Experience Layer 使用 Amazon Cognito 为用户生成访问令牌,然后在面向公众的 API 上进行验证。
- 如果验证成功,体验层 lambda ( 好朋友拉姆达 ) 使用其临时 AWS 凭证使用 SigV4 和 AWS STS 专门针对它想要使用的私有域 API( 目标域服务 )。
- 向域账户 API 发出签名请求,域账户中的私有 API 网关使用 IAM 身份验证验证签名请求。
此过程的基本代码仓库示例如下所示:
[
GitHub - leegilmorecode/serverless-api-2-api: 将 Cognito 用于外部 API 和…
将 Cognito 用于外部 API 和 IAM 身份验证以调用内部 API 的示例 - GitHub …
github.com
](https://github.com/leegilmorecode/serverless-api-2-api)
下图显示了您的 API 网关资源策略如何与我们的域服务跨账户工作以根据需要绑定我们的权限,其中一个成功,一个不成功:
An example of our policies cross-account when working with our Domain Service APIs
我们可以看到来自域 2 服务的调用将失败,因为域 3 API 上的资源策略只允许来自域 1 的 execute-api:invoke。
我们通过使用 AWS PrivateLink 和 VPC 终端节点跨账户,在 AWS 主干网络上保持所有网络流量私有,如下所示,无论是在 经验 和一个或多个 域 ,或域到域:
Example of the communication cross account using IAM authentication and AWS PrivateLink
这大大减少了我们对不良行为者的攻击面,意味着我们在全球范围内有一个内部 m2m 通信标准,该方法不依赖于 Amazon Cognito,我们可以将身份验证范围缩小到每个帐户的 API 上的调用 lambda 和 API 资源/方法,如果需要,我们不需要在无服务器中缓存访问令牌( 就像我们使用客户凭证授予 Cognito 流一样 ),当我们集中我们的 VPC 端点时,它是具有成本效益的 ( 见下文 )。
[
集中访问 VPC 私有终端节点
VPC 终端节点允许您将您的 VPC 私下连接到支持的 AWS 服务,而无需互联网网关……
docs.aws.amazon.com
笔记 :在第 5 部分中,我们将讨论上述架构中有多少可以抽象为可重用的 L3/L4 CDK 构造以在组织内使用,从而大大减少团队的认知负担,并在最佳实践中进行烘焙。
✔️ 数据库选择和消费者
域服务的主要考虑因素之一是您的 数据库的选择 ,正如你将拥有 ** 1..n** 您的域 API 的消费者,以及 您永远不会通过其 API 知道他们的访问模式要求是什么 .
“Domain Services 的一个关键考虑因素是您对数据库的选择,因为您将有 1..n 个 Domain API 消费者,您永远不会知道他们的访问模式要求是什么。” — 李吉尔摩
如下图所示,我们有 经验 和别的 域 作为任何给定域服务的消费者:
We will never know what our 1..n consumers will need, so we need to ensure we have flexible access patterns
我们可以在上面看到,我们的许多消费者可能需要执行 ** 分页、计数、聚合、过滤和排序等** 全部同时;因此,我们需要确保我们的域服务数据库选择是灵活的且面向未来的,以允许这样做。
“因此我们需要确保我们的域服务数据库选择灵活且面向未来。” — 李吉尔摩
这让我们在 AWS 数据库世界中为我们的域提供了两个关键选择,它们在访问模式方面非常灵活:
✔️ 亚马逊文档数据库 ( 基于文档的数据库 )。
✔️ Amazon RDS/Aurora ( 基于 SQL 的数据库 )。
DynamoDB 是一种无服务器数据库技术,您需要预先了解您的访问模式,因此由于不灵活,这使得为您的域服务选择数据库非常糟糕,除非需求是已知的、确定的并且确实非常简单。
[
AWS 上的专用数据库 |亚马逊网络服务
使用完全托管的专用数据库实现数据基础架构现代化 选择正确的专用引擎……
aws.amazon.com
](https://aws.amazon.com/products/databases/)
有些人可能会考虑将数据存储技术组合用于他们的域服务,例如 DynamoDB/DynamoDB 流(写入)和 RDS/Aurora(读取),将读取和写入分开。这不适用于域 API 策略,因为与写入相比,您的读取始终最终是一致的,如果您的消费者不知道,这可能会让他们感到困惑和容易出错(即这在 API 优先的公司中不起作用)。
✔️ 来龙去脉——合约的力量
域服务应该 只要 可以通过它们定义良好的版本化 API 访问,并且所有内部都应该被封装( 如下图所示 )
We always go via well defined APIs and never share our internals (bounded context)
如您所见,我们不应该让另一个域服务访问另一个域服务数据库( 或队列,主题,任何事情! )。
域服务只能在 AWS 网络上从其他域或 Experience Layer BFF 访问;因此无法使用 CURL、Postman 等访问
概括
所以让我们总结一下对 领域层 及其域服务 无服务器架构层 :
✔️ 定义明确的版本化 API 和事件确保消费者了解如何与我们的域进行交互。 ( 在讨论事件的数据层时更多 )
✔️ 域接口意味着我们可以在不影响消费者的情况下更改域服务的内部结构。
✔️ 我们的域服务不能被外部世界访问,只能使用机器对机器流访问。 ( 即使用私有 API 网关和 IAM 身份验证 )。
✔️ 我们确保消费者不会直接与我们域的内部交互,这些内部被很好地封装在接口(API 和事件)后面,并且只能通过我们定义良好的 API 和事件。
✔️ 域逻辑可以被其他域服务或体验使用,防止贫血域在分布式单体中分裂。
我希望您发现在涉及无服务器架构层时,涵盖领域层是什么很有用。在本系列的下一篇文章中,我们将介绍 数据层 .
收尾
请 去订阅我的 YouTube 频道 对于类似的内容!
我也很想就以下任何一项与您联系:
https://www.linkedin.com/in/lee-james-gilmore/
https://twitter.com/LeeJamesGilmore
如果您喜欢这些帖子,请关注我的个人资料 李·詹姆斯·吉尔摩 更多帖子/系列,别忘了联系并打个招呼
如果您喜欢,还请使用帖子底部的“拍手”功能! ( 你可以多次鼓掌!! )
关于我
“ 大家好,我是 Lee,AWS 社区建设者、博主、AWS 认证云架构师和全球企业无服务器架构师,驻英国;目前在 City Electrical Factors(英国)和 City Electric Supply(美国)工作,过去 6 年主要在 AWS 上从事全栈 JavaScript 工作。
我认为自己是一名无服务器倡导者,热爱 AWS、创新、软件架构和技术。 ”
***** 所提供的信息是我个人的观点,我对信息的使用不承担任何责任。 *****
您可能还对以下内容感兴趣:
[
无服务器内容
我所有无服务器内容的索引,可在一个地方轻松浏览,包括视频、博客文章等。
leejamesgilmore.medium.com
](/serverless-content-46ef5b562d8e)
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通