

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# 使用 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*

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

此模式說明如何使用 AWS Lambda 在六邊形架構中建構 Python 專案。模式使用 AWS 雲端開發套件 (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
+ Poetry 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 版或更新版本

## Architecture
<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_tw/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 個 AWS 服務和軟體即服務 (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 套件和 layer。

**Code**

此模式的程式碼可在 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 Key Management Service (AWS KMS) 中使用客戶受管金鑰來加密 [Amazon CloudWatch 日誌群組](https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/encrypt-log-data-kms.html)和 [Amazon 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>


| 任務 | Description | 所需的技能 | 
| --- | --- | --- | 
| 建立您自己的儲存庫。 | [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_tw/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_tw/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_tw/prescriptive-guidance/latest/patterns/structure-a-python-project-in-hexagonal-architecture-using-aws-lambda.html) | 應用程式開發人員 | 
| 執行單位測試，選項 1：使用 Visual Studio 程式碼。 | [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_tw/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_tw/prescriptive-guidance/latest/patterns/structure-a-python-project-in-hexagonal-architecture-using-aws-lambda.html) | 應用程式開發人員 | 

### 部署和測試應用程式
<a name="deploy-and-test-the-application"></a>


| 任務 | Description | 所需的技能 | 
| --- | --- | --- | 
| 請求臨時登入資料。 | 若要在執行 時在 Shell 上擁有 AWS 登入資料`cdk deploy`，請使用 AWS IAM Identity Center (AWS Single Sign-On 的後續版本） 建立臨時登入資料。如需說明，請參閱部落格文章[如何擷取 CLI 搭配 AWS IAM Identity Center 使用的短期憑證](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_tw/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 操作和請求/回應訊息的詳細資訊，請參閱 GitHub 儲存庫中 [readme 檔案的 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_tw/prescriptive-guidance/latest/patterns/structure-a-python-project-in-hexagonal-architecture-using-aws-lambda.html) | 應用程式開發人員、AWS DevOps | 

### 開發服務
<a name="develop-the-service"></a>


| 任務 | Description | 所需的技能 | 
| --- | --- | --- | 
| 撰寫商業網域的單位測試。 | [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_tw/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_tw/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_tw/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_tw/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_tw/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_tw/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/)
+ [適用於 Python 的 AWS Lambda Powertools](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/)

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