

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# 使用 AWS Lambda 以六边形架构构建 Python 项目
<a name="structure-a-python-project-in-hexagonal-architecture-using-aws-lambda"></a>

*Furkan Oruc、Dominik Goby、Darius Kunce 和 Michal Ploski，Amazon Web Services*

## Summary
<a name="structure-a-python-project-in-hexagonal-architecture-using-aws-lambda-summary"></a>

此模式展示了如何使用 AWS Lambda 以六边形架构构建 Python 项目。该模式使用 AWS Cloud Development Kit (AWS CDK) 作为基础设施即代码（IaC）工具，使用 Amazon API Gateway 作为 REST API，使用 Amazon DynamoDB 作为持久层。六边形架构遵循域驱动设计原则。在六边形架构中，软件由三个组件组成：域、端口和适配器。有关六边形架构及其优势的详细信息，请参阅指南[在 AWS 上构建六边形架构](https://docs.aws.amazon.com/prescriptive-guidance/latest/hexagonal-architectures/)*。*

## 先决条件和限制
<a name="structure-a-python-project-in-hexagonal-architecture-using-aws-lambda-prereqs"></a>

**先决条件**
+ 一个活跃的 AWS 账户
+ Python 经验
+ 熟悉 AWS Lambda、AWS CDK、Amazon API Gateway 和 DynamoDB
+  GitHub 账户（参见[注册说明](https://docs.github.com/en/get-started/signing-up-for-github/signing-up-for-a-new-github-account)）
+ Git（请参阅[安装说明](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git)）
+ 一种代码编辑器，用于进行更改并将代码推送到 GitHub （例如，[Visual Studio Code](https://code.visualstudio.com/) 或 [JetBrains PyCharm](https://www.jetbrains.com/pycharm/)）
+ 已安装 Docker，而且 Docker 进程守护程序已经启动并且正在运行

**产品版本**
+ Git 版本 2.24.3 或更高版本
+ Python 版本 3.7 或更高版本
+ AWS CDK v2
+ EMR 版本 1.1.13 或更高版本
+ AWS Lambda Powertools for Python 版本 1.25.6 或更高版本
+ pytest 版本 7.1.1 或更高版本
+ Moto 版本 3.1.9 或更高版本
+ pydantic 版本 1.9.0 或更高版本
+ Boto3 版本 1.22.4 或更高版本
+ mypy-boto3-dynamodb 版本 1.24.0 或更高版本

## 架构
<a name="structure-a-python-project-in-hexagonal-architecture-using-aws-lambda-architecture"></a>

**目标技术堆栈 **

目标技术堆栈由使用 API Gateway、Lambda 和 DynamoDB 的 Python 服务构成。该服务使用 DynamoDB 适配器保存数据。它提供了使用 Lambda 作为入口点的函数。该服务使用 Amazon API Gateway 公开 REST API。API 使用 AWS Identity and Access Management (IAM) [对客户端执行身份验证](https://docs.aws.amazon.com/apigateway/latest/developerguide/permissions.html)。

**目标架构 **

为说明实现方式，此模式部署了无服务器目标架构。客户端可向 API Gateway 端点发送请求。API Gateway 将请求转发至实现六边形架构模式的目标 Lambda 函数。Lambda 函数可对 DynamoDB 表执行创建、读取、更新和删除（CRUD）操作。


| 
| 
| 此模式已在 PoC 环境中接受了测试。在将任何架构部署到生产环境之前，您必须执行安全审查，以便识别威胁模式和创建安全的代码库。 | 
| --- |

![\[用于以六边形架构构建 Python 项目的目标架构\]](http://docs.aws.amazon.com/zh_cn/prescriptive-guidance/latest/patterns/images/pattern-img/25bd7169-ea5e-4a21-a865-c91c30a3c0da/images/de0d4f0d-ad19-43ec-bd10-676b25477b64.png)


该 API 支持对产品实体的五种操作：
+ `GET /products` 返回所有产品。
+ `POST /products` 创建新产品。
+ `GET /products/{id}` 返回特定产品。
+ `PUT /products/{id}` 更新特定产品。
+ `DELETE /products/{id}` 删除特定产品。

您可使用以下文件夹结构来组织项目，以遵循六边形架构模式：  

```
app/  # application code
|--- adapters/  # implementation of the ports defined in the domain
     |--- tests/  # adapter unit tests
|--- entrypoints/  # primary adapters, entry points
     |--- api/  # api entry point
          |--- model/  # api model
          |--- tests/  # end to end api tests
|--- domain/  # domain to implement business logic using hexagonal architecture
     |--- command_handlers/  # handlers used to execute commands on the domain
     |--- commands/  # commands on the domain
     |--- events/  # events triggered via the domain
     |--- exceptions/  # exceptions defined on the domain
     |--- model/  # domain model
     |--- ports/  # abstractions used for external communication
     |--- tests/  # domain tests
|--- libraries/  # List of 3rd party libraries used by the Lambda function
infra/  # infrastructure code
simple-crud-app.py  # AWS CDK v2 app
```

## 工具
<a name="structure-a-python-project-in-hexagonal-architecture-using-aws-lambda-tools"></a>

**AWS 服务**
+ [Amazon API Gateway](https://aws.amazon.com/api-gateway/) 是一项完全托管的服务，可让开发人员轻松创建、发布、维护、监控和保护 APIs 任何规模。
+ [Amazon DynamoDB](https://aws.amazon.com/dynamodb/) 是一个完全托管的无服务器键值的 NoSQL 数据库，专为运行任何规模的高性能应用程序而设计。
+ [AWS Lambda](https://aws.amazon.com/lambda/) 是一项无服务器、事件驱动计算服务，让您能够为几乎任何类型的应用程序或后端服务运行代码，而无需预调配或管理服务器。您可以从 200 多种 Amazon Web Services 和软件即服务（SaaS）应用程序启动 Lambda 函数，并且只需为您使用的部分付费。

**工具**
+ [Git](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git) 用作此模式中代码开发的版本控制系统。
+ [Python](https://www.python.org/) 用作此模式的编程语言。Python 提供高级数据结构和面向对象编程方法。AWS Lambda 提供内置的 Python 运行时系统，可简化 Python 服务的操作。
+ [Visual Studio Code](https://code.visualstudio.com/) 用作用于开发和测试此模式的 IDE。您可以使用任何支持 Python 开发的 IDE（例如 [PyCharm](https://www.jetbrains.com/pycharm/)）。
+ [AWS Cloud Development Kit（AWS CDK）](https://aws.amazon.com/cdk/)是一个开源软件开发框架，能够让您使用熟悉的编程语言来定义云应用程序资源。此模式使用 CDK 以代码形式编写和部署云基础设施。
+ [Poetry](https://python-poetry.org/) 用于管理模式中的依赖项。
+ AWS CDK 使用 [Docker](https://www.docker.com/) 构建 Lambda 包和层。

**代码**

此模式的代码可在 GitHub [Lambda 六边形架构示例存储](https://github.com/aws-samples/lambda-hexagonal-architecture-sample)库中找到。

## 最佳实践
<a name="structure-a-python-project-in-hexagonal-architecture-using-aws-lambda-best-practices"></a>

要在生产环境使用此模式，请遵循以下最佳实践：
+ 使用 AWS 密钥管理服务 (AWS KMS) 中的客户托管密钥对[亚马逊 CloudWatch 日志组和亚马逊](https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/encrypt-log-data-kms.html) [DynamoDB 表](https://docs.aws.amazon.com/kms/latest/developerguide/services-dynamodb.html)进行加密。
+ 为 [Amazon API Gateway 配置 AWS WAF](https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-control-access-aws-waf.html)，以允许仅从贵组织的网络进行访问。
+ 如果 IAM 不能满足您的需求，可考虑其他的 API Gateway 授权选项。例如，您可使用 [Amazon Cognito 用户池](https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-integrate-with-cognito.html)或 [API Gateway Lambda 授权者](https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-use-lambda-authorizer.html)。
+ 使用 [DynamoDB 备份](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/BackupRestore.html)。
+ 使用[虚拟私有云（VPC）部署](https://docs.aws.amazon.com/lambda/latest/dg/configuration-vpc.html)来配置 Lambda 函数，将网络流量保持在云内。
+ 为[跨源资源共享 (CORS) 预检](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS)更新允许的源配置，以限制仅访问请求的源域。
+ 使用 [cdk-nag](https://docs.aws.amazon.com/prescriptive-guidance/latest/patterns/check-aws-cdk-applications-or-cloudformation-templates-for-best-practices-by-using-cdk-nag-rule-packs.html) 检查 AWS CDK 代码，了解安全最佳实践。
+ 考虑使用代码扫描工具来查找代码中常见的安全问题。例如，[Bandit](https://bandit.readthedocs.io/en/latest/) 是旨在查找 Python 代码中常见安全问题的工具。[Pip-audit](https://pypi.org/project/pip-audit/) 将扫描 Python 环境中是否存在已知漏洞的程序包。

此模式使用 [AWS X-Ray](https://aws.amazon.com/xray/?nc1=h_ls) 通过应用程序的入口点、域和适配器跟踪请求。AWS X-Ray 帮助开发人员识别瓶颈并确定高延迟以提高应用程序性能。

## 操作说明
<a name="structure-a-python-project-in-hexagonal-architecture-using-aws-lambda-epics"></a>

### 初始化项目
<a name="initialize-the-project"></a>


| Task | 说明 | 所需技能 | 
| --- | --- | --- | 
| 创建您自己的存储库。 | [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/prescriptive-guidance/latest/patterns/structure-a-python-project-in-hexagonal-architecture-using-aws-lambda.html) | 应用程序开发人员 | 
| 安装依赖项。 | [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/prescriptive-guidance/latest/patterns/structure-a-python-project-in-hexagonal-architecture-using-aws-lambda.html) | 应用程序开发人员 | 
| 配置您的 IDE。 | 我们推荐 Visual Studio Code，但您可以使用您选择的任何支持 Python 的 IDE。以下步骤适用于 Visual Studio Code。[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/prescriptive-guidance/latest/patterns/structure-a-python-project-in-hexagonal-architecture-using-aws-lambda.html) | 应用程序开发人员 | 
| 运行单元测试，选项 1：使用 Visual Studio Code。 | [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/prescriptive-guidance/latest/patterns/structure-a-python-project-in-hexagonal-architecture-using-aws-lambda.html) | 应用程序开发人员 | 
| 运行单元测试，选项 2：使用 Shell 命令。 | [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/prescriptive-guidance/latest/patterns/structure-a-python-project-in-hexagonal-architecture-using-aws-lambda.html) | 应用程序开发人员 | 

### 部署和测试应用程序
<a name="deploy-and-test-the-application"></a>


| Task | 说明 | 所需技能 | 
| --- | --- | --- | 
| 请求临时凭证。 | 要在运行 `cdk deploy` 时在 Shell 中使用 AWS 凭证，请使用 AWS IAM Identity Center（AWS Single Sign-On 的后继任务）创建临时凭证。有关说明，请参阅博客文章[如何检索短期凭证，以便在 AWS IAM Identity Center 使用 CLI](https://aws.amazon.com/blogs/security/aws-single-sign-on-now-enables-command-line-interface-access-for-aws-accounts-using-corporate-credentials/)。 | AWS 应用程序开发人员 DevOps | 
| 部署 应用程序。 | [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/prescriptive-guidance/latest/patterns/structure-a-python-project-in-hexagonal-architecture-using-aws-lambda.html) | AWS 应用程序开发人员 DevOps | 
| 测试 API，选项 1：使用控制台。 | 使用 [API Gateway 控制台](https://docs.aws.amazon.com/apigateway/latest/developerguide/how-to-test-method.html)测试 API。有关 API 操作和 request/response 消息的更多信息，请参阅 GitHub 存储库中[自述文件的 API 用法部分](https://github.com/aws-samples/lambda-hexagonal-architecture-sample/blob/main/README.md#api-usage)。 | AWS 应用程序开发人员 DevOps | 
| 测试 API，选项 2：使用 Postman。 | 如果您要使用 [Postman](https://www.postman.com/) 这样的工具，请执行以下操作：[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/prescriptive-guidance/latest/patterns/structure-a-python-project-in-hexagonal-architecture-using-aws-lambda.html) | AWS 应用程序开发人员 DevOps | 

### 开发服务
<a name="develop-the-service"></a>


| Task | 说明 | 所需技能 | 
| --- | --- | --- | 
| 为业务域编写单元测试。 | [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/prescriptive-guidance/latest/patterns/structure-a-python-project-in-hexagonal-architecture-using-aws-lambda.html) | 应用程序开发人员 | 
| 实施命令和命令处理程序。 | [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/prescriptive-guidance/latest/patterns/structure-a-python-project-in-hexagonal-architecture-using-aws-lambda.html) | 应用程序开发人员 | 
| 为辅助适配器编写集成测试。 | [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/prescriptive-guidance/latest/patterns/structure-a-python-project-in-hexagonal-architecture-using-aws-lambda.html) | 应用程序开发人员 | 
| 实施辅助适配器。 | [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/prescriptive-guidance/latest/patterns/structure-a-python-project-in-hexagonal-architecture-using-aws-lambda.html) | 应用程序开发人员 | 
| 写 end-to-end测试。 | [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/prescriptive-guidance/latest/patterns/structure-a-python-project-in-hexagonal-architecture-using-aws-lambda.html) | 应用程序开发人员 | 
| 实施主适配器。 | [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/prescriptive-guidance/latest/patterns/structure-a-python-project-in-hexagonal-architecture-using-aws-lambda.html) | 应用程序开发人员 | 

## 相关资源
<a name="structure-a-python-project-in-hexagonal-architecture-using-aws-lambda-resources"></a>

**APG 指南**
+ [在 AWS 上构建六边形架构](https://docs.aws.amazon.com/prescriptive-guidance/latest/hexagonal-architectures/)

**AWS 参考**
+ [AWS Lambda 文档](https://docs.aws.amazon.com/lambda/)
+ [AWS CDK 文档](https://docs.aws.amazon.com/cdk/)
  + [您的第一个 AWS CDK 应用程序](https://docs.aws.amazon.com/cdk/v2/guide/hello_world.html)
+ [API Gateway 文档](https://docs.aws.amazon.com/apigateway/)
  + [使用 IAM 权限控制对 API 的访问](https://docs.aws.amazon.com/apigateway/latest/developerguide/permissions.html)
  + [使用 API Gateway 控制台测试 REST API 方法](https://docs.aws.amazon.com/apigateway/latest/developerguide/how-to-test-method.html)
+ [Amazon DynamoDB 文档](https://docs.aws.amazon.com/dynamodb/)

**工具**
+ [git-scm.com 网站](https://git-scm.com/)
+ [安装 Git](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git)
+ [创建新 GitHub 存储库](https://docs.github.com/en/repositories/creating-and-managing-repositories/creating-a-new-repository)
+ [Python 网站](https://www.python.org/)
+ [AWS Lambda Powertools for Python](https://docs.powertools.aws.dev/lambda/python/latest/)
+ [Postman 网站](https://www.postman.com/)
+ [Python 模拟对象库](https://docs.python.org/3/library/unittest.mock.html)
+ [Poetry 网站](https://python-poetry.org/)

**IDEs**
+ [Visual Studio Code 网站](https://code.visualstudio.com/)
+ [PyCharm 网站](https://www.jetbrains.com/pycharm/)