

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

# 在 Amazon API Gateway 中使用自訂網域實作路徑型 API 版本控制
<a name="implement-path-based-api-versioning-by-using-custom-domains"></a>

*Corey Schnedl、Marcel Barbosa、Mario Lopez Martinez、Anbazhagan Ponnuswamy、Gaurav Samudra 和 Abhilash Vinod、Amazon Web Services*

## 摘要
<a name="implement-path-based-api-versioning-by-using-custom-domains-summary"></a>

此模式示範如何使用[自訂網域](https://docs.aws.amazon.com/apigateway/latest/developerguide/how-to-custom-domains.html)的 [API 映射](https://docs.aws.amazon.com/apigateway/latest/developerguide/rest-api-mappings.html)功能，為 Amazon API Gateway 實作以路徑為基礎的 API 版本控制解決方案。

Amazon API Gateway 是一項全受管服務，可用於建立、發佈、維護、監控和保護任何規模APIs。透過使用服務的自訂網域功能，您可以建立更簡單的自訂網域名稱，並提供更直覺URLs 給您的 API 使用者。您可以使用 API 映射將 API 階段連線至自訂網域名稱。建立網域名稱並設定 DNS 記錄之後，您可以使用 API 映射，透過自訂網域名稱將流量傳送至您的 API。

在 API 公開可用之後，消費者會使用它。隨著公有 API 的演進，其服務合約也會演進以反映新功能。不過，變更或移除現有功能並不明智。任何中斷變更都可能會影響消費者的應用程式，並在執行時間中斷它們。API 版本控制對於避免破壞回溯相容性和破壞合約非常重要。

您需要明確的 API 版本控制策略，以協助消費者採用這些策略。使用路徑型 URLs版本控制 APIs 是最直接且常用的方法。在此類型的版本控制中，版本會明確定義為 API URIs的一部分。下列範例 URLs顯示消費者如何使用 URI 為其請求指定 API 版本：

`https://api.example.com/api/v1/orders `

`https://api.example.com/api/v2/orders `

`https://api.example.com/api/vX/orders`

此模式使用 AWS Cloud Development Kit (AWS CDK) 為您的 API 建置、部署和測試可擴展路徑型版本控制解決方案的範例實作。 AWS CDK 是一種開放原始碼軟體開發架構，可使用熟悉的程式設計語言來建模和佈建雲端應用程式資源。

## 先決條件和限制
<a name="implement-path-based-api-versioning-by-using-custom-domains-prereqs"></a>

**先決條件 **
+ 作用中 AWS 帳戶。
+ 需要擁有網域才能使用此模式的範例儲存庫，以及使用 Amazon API Gateway 自訂網域功能。您可以使用 Amazon Route 53 為您的組織建立和管理網域。如需有關如何使用 Route 53 註冊或轉移網域的資訊，請參閱 Route 53 文件中的[註冊新網域](https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/domain-register-update.html)。
+ 在設定 API 的自訂網域名稱之前，您必須備妥 [SSL/TLS 憑證](https://docs.aws.amazon.com/apigateway/latest/developerguide/how-to-specify-certificate-for-custom-domain-name.html) AWS Certificate Manager。
+ 您必須建立或更新 DNS 提供者的資源記錄，以映射至您的 API 端點。如果沒有這類映射，則綁定自訂網域名稱的 API 請求無法到達 API Gateway。

**限制 **
+  AWS 區域 在所有 中，自訂網域名稱必須是唯一的 AWS 帳戶。
+ 若要設定具有多個層級的 API 映射，您必須使用區域性自訂網域名稱和 TLS 1.2 安全政策。
+ 在 API 映射中，自訂網域名稱和映射APIs 必須位於相同的 中 AWS 帳戶。
+ API 映射只能包含字母、數字和下列字元： `$-_.+!*'()/`
+ API 映射中路徑的最大長度為 300 個字元。
+ 您可以為每個域名設定具有 200 個具多個層級的 API 映射。
+ 您只能將 HTTP APIs 映射至具有 TLS 1.2 安全政策的區域性自訂網域名稱。
+ 您無法將 WebSocket APIs對應至與 HTTP API 或 REST API 相同的自訂網域名稱。
+ 有些 AWS 服務 無法全部使用 AWS 區域。如需區域可用性，請參閱[AWS 依區域的服務](https://aws.amazon.com/about-aws/global-infrastructure/regional-product-services/)。如需特定端點，請參閱[服務端點和配額](https://docs.aws.amazon.com/general/latest/gr/aws-service-information.html)，然後選擇服務的連結。

**產品版本**
+ 此範例實作在 [AWS CDK TypeScript 2.149.0 ](https://docs.aws.amazon.com/cdk/v2/guide/work-with-cdk-typescript.html)版中使用 。

## Architecture
<a name="implement-path-based-api-versioning-by-using-custom-domains-architecture"></a>

下圖顯示架構工作流程。

![\[使用 API 映射和自訂網域來實作路徑型 API 版本控制解決方案的工作流程。\]](http://docs.aws.amazon.com/zh_tw/prescriptive-guidance/latest/patterns/images/pattern-img/e1b32d2b-410f-4ace-967e-f0b8aaf0304c/images/fa9f04f1-efa6-4fb1-a541-ae3da4076b00.png)


此圖展示了以下要點：

1. API 使用者向 Amazon API Gateway 傳送具有自訂網域名稱的請求。

1. API Gateway 會根據請求 URL 中指定的路徑，將使用者的請求動態路由到 API Gateway 的適當執行個體和階段。下表顯示如何將不同 URL 型路徑路由至不同 API Gateway 執行個體之特定階段的範例。    
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_tw/prescriptive-guidance/latest/patterns/implement-path-based-api-versioning-by-using-custom-domains.html)

1. 目的地 API Gateway 執行個體會處理請求，並將結果傳回給使用者。

**自動化和擴展**

我們建議您針對 API 的每個版本使用不同的 AWS CloudFormation 堆疊。透過此方法，您可以在可由自訂網域 APIs 的後端 API 之間進行完全隔離。這種方法的優點是，您可以獨立部署或刪除不同版本的 API，而不會帶來修改其他 API 的風險。這種方法透過隔離 CloudFormation 堆疊來提高彈性。此外，它還為您的 API 提供不同的後端選項 AWS Lambda AWS Fargate，例如 HTTP 端點和 的動作 AWS 服務。

您可以使用 Git 分支策略，例如 [Gitflow](https://docs.aws.amazon.com/prescriptive-guidance/latest/choosing-git-branch-approach/gitflow-branching-strategy.html)，搭配隔離的 CloudFormation 堆疊來管理部署到不同 API 版本的原始碼。透過使用此選項，您可以維護不同版本的 API，而不需要複製新版本的原始程式碼。使用 Gitflow，您可以在執行版本時，將標籤新增至 git 儲存庫中的遞交。因此，您擁有與特定版本相關的原始程式碼的完整快照。由於需要執行更新，您可以查看特定版本的程式碼、進行更新，然後將更新的原始程式碼部署到與對應主要版本一致的 CloudFormation 堆疊。這種方法可降低破壞另一個 API 版本的風險，因為每個 API 版本都有隔離的原始程式碼，並部署到單獨的 CloudFormation 堆疊。

## 工具
<a name="implement-path-based-api-versioning-by-using-custom-domains-tools"></a>

**AWS 服務**
+ [Amazon API Gateway](https://docs.aws.amazon.com/apigateway/latest/developerguide/welcome.html) 可協助您建立、發佈、維護、監控和保護任何規模的 REST、HTTP 和 WebSocket APIs。
+ [AWS Certificate Manager (ACM)](https://docs.aws.amazon.com/acm/latest/userguide/acm-overview.html) 可協助您建立、存放和續約公有和私有 SSL/TLS X.509 憑證和金鑰，以保護 AWS 網站和應用程式。
+ [AWS Cloud Development Kit (AWS CDK)](https://docs.aws.amazon.com/cdk/v2/guide/home.html) 是一種開放原始碼軟體開發架構，可讓您在程式碼中定義雲端基礎設施並透過其佈建 CloudFormation。此模式的範例實作使用 [AWS CDK TypeScript 中的](https://docs.aws.amazon.com/cdk/v2/guide/work-with-cdk-typescript.html) 。在 TypeScript AWS CDK 中使用 會使用熟悉的工具，包括 Microsoft TypeScript 編譯器 (`tsc`)、[Node.js](https://nodejs.org/) 和節點套件管理員 (`npm`)。如果您願意，雖然此模式中的範例使用 ，但您可以使用 [Yarn](https://yarnpkg.com/)`npm`。構成[AWS 建構程式庫](https://docs.aws.amazon.com/cdk/v2/guide/libraries.html#libraries-construct)的模組會透過儲存`npm `庫 [npmjs.org](https://docs.npmjs.com/) 進行分發。
+ [CloudFormation](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/Welcome.html) 可協助您設定 AWS 資源、快速且一致地佈建資源，以及在整個 AWS 帳戶 和 生命週期中管理資源 AWS 區域。
+ [AWS Lambda](https://docs.aws.amazon.com/lambda/latest/dg/welcome.html) 是一項運算服務，可協助您執行程式碼，無需佈建或管理伺服器。它只會在需要時執行程式碼並自動擴展，因此您只需按使用的運算時間付費。
+ [Amazon Route 53](https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/Welcome.html) 是一種可用性高、可擴展性強的 DNS Web 服務。
+ [AWS WAF](https://docs.aws.amazon.com/waf/latest/developerguide/what-is-aws-waf.html) 是一種 Web 應用程式防火牆，可協助您監控轉送至受保護 Web 應用程式資源的 HTTP 和 HTTPS 請求。

**其他工具**
+ [Bruno](https://www.usebruno.com/) 是開放原始碼且易於 Git 的 API 測試用戶端。
+ [cdk-nag](https://github.com/cdklabs/cdk-nag) 是一種開放原始碼公用程式，可透過使用規則套件來檢查 AWS CDK 應用程式是否有最佳實務。

**程式碼儲存庫**

此模式的程式碼可在 GitHub [path-based-versioning-with-api-gateway](https://github.com/aws-samples/path-based-versioning-with-api-gateway)儲存庫中使用。

## 最佳實務
<a name="implement-path-based-api-versioning-by-using-custom-domains-best-practices"></a>
+ 使用強大的持續整合和持續交付 (CI/CD) 管道，自動化使用 建置之 CloudFormation 堆疊的測試和部署 AWS CDK。如需有關此建議的詳細資訊，請參閱 [AWS Well-Architected DevOps 指南](https://docs.aws.amazon.com/wellarchitected/latest/devops-guidance/devops-guidance.html)。
+ AWS WAF 是受管防火牆，可輕鬆與 Amazon API Gateway 等服務整合。雖然 AWS WAF 不是此版本控制模式運作的必要元件，但我們建議將 做為安全最佳實務， AWS WAF 納入 API Gateway。
+ 鼓勵 API 取用者定期升級至最新版本的 API，以便有效棄用和移除舊版的 API。
+ 在生產設定中使用此方法之前，請為您的 API 實作防火牆和授權策略。
+  AWS 帳戶 使用最低權限存取模型實作對 AWS 資源管理的存取。 [https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html#grant-least-privilege](https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html#grant-least-privilege)
+ 若要針對使用 建置的應用程式強制執行最佳實務和安全性建議 AWS CDK，建議您使用 [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)。

## 史詩
<a name="implement-path-based-api-versioning-by-using-custom-domains-epics"></a>

### 準備您的本機環境
<a name="prepare-your-local-environment"></a>


| 任務 | Description | 所需的技能 | 
| --- | --- | --- | 
| 複製儲存庫。 | 若要複製範例應用程式儲存庫，請執行下列命令：<pre>git clone https://github.com/aws-samples/path-based-versioning-with-api-gateway</pre> | 應用程式開發人員 | 
| 導覽至複製的儲存庫。 | 若要導覽至複製的儲存庫資料夾位置，請執行下列命令：<pre>cd api-gateway-custom-domain-versioning</pre> | 應用程式開發人員 | 
| 安裝所需的依存項目。 | 若要安裝必要的相依性，請執行下列命令：<pre>npm install </pre> | 應用程式開發人員 | 

### 部署 CloudFormation 路由堆疊
<a name="deploy-the-cfnshort-routing-stack"></a>


| 任務 | Description | 所需的技能 | 
| --- | --- | --- | 
| 啟動路由堆疊的部署。 | 若要啟動 CloudFormation 路由堆疊 的部署`CustomDomainRouterStack`，請執行下列命令，`example.com`將 取代為您擁有的網域名稱：<pre>npx cdk deploy CustomDomainRouterStack --parameters PrerequisiteDomainName=example.com</pre>在下列網域 DNS 驗證任務成功執行之前，堆疊部署不會成功。 | 應用程式開發人員 | 

### 驗證網域所有權
<a name="verify-domain-ownership"></a>


| 任務 | Description | 所需的技能 | 
| --- | --- | --- | 
| 驗證網域的擁有權。 | 在您證明相關聯網域的擁有權之前，憑證將保持**待定驗證**狀態。若要證明擁有權，請將 CNAME 記錄新增至與網域相關聯的託管區域。如需詳細資訊，請參閱 AWS Certificate Manager 文件中的 [DNS 驗證](https://docs.aws.amazon.com/acm/latest/userguide/dns-validation.html)。新增適當的記錄可讓`CustomDomainRouterStack`部署成功。 | 應用程式開發人員、AWS 系統管理員、網路管理員 | 
| 建立別名記錄以指向您的 API Gateway 自訂網域。 | 成功發出並驗證憑證後，[請建立指向 Amazon API Gateway 自訂網域 URL 的 DNS 記錄](https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-regional-api-custom-domain-create.html#apigateway-regional-api-custom-domain-dns-record)。 Amazon API Gateway 自訂網域 URL 由自訂網域的佈建唯一產生，並指定為 CloudFormation 輸出參數。以下是[記錄的範例](https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/resource-record-sets-values-basic.html)：**路由政策**：簡易路由**記錄名稱**： `demo.api-gateway-custom-domain-versioning.example.com`**Alias (別名)**：是**記錄類型**：指向 AWS 資源的 "A" 類型的 DNS 記錄**Value (值)**：`d-xxxxxxxxxx.execute-api.xx-xxxx-x.amazonaws.com`**TTL （秒）**：300 | 應用程式開發人員、AWS 系統管理員、網路管理員 | 

### 部署 CloudFormation 堆疊並叫用 API
<a name="deploy-cfnshort-stacks-and-invoke-the-api"></a>


| 任務 | Description | 所需的技能 | 
| --- | --- | --- | 
| 部署`ApiStackV1`堆疊。 | 若要部署`ApiStackV1`堆疊，請使用下列命令：<pre>npm run deploy-v1</pre>下列 CDK 程式碼新增 API 映射：<pre>var apiMapping = new CfnApiMapping(this, "ApiMapping", {<br />      apiId: this.lambdaRestApi.restApiId,<br />      domainName: props.customDomainName.domainName,<br />      stage: "api",<br />      apiMappingKey: "api/v1",<br />    });</pre> | 應用程式開發人員 | 
| 部署`ApiStackV2`堆疊。 | 若要部署`ApiStackV2`堆疊，請使用下列命令：<pre>npm run deploy-v2</pre> | 應用程式開發人員 | 
| 叫用 API。 | 若要使用 Bruno 叫用 API 並測試 API 端點，請參閱[其他資訊](#implement-path-based-api-versioning-by-using-custom-domains-additional)中的指示。 | 應用程式開發人員 | 

### 清除資源
<a name="clean-up-resources"></a>


| 任務 | Description | 所需的技能 | 
| --- | --- | --- | 
| 清除資源。 | 若要銷毀與此範例應用程式相關聯的資源，請使用下列命令：<pre>npx cdk destroy --all</pre>請務必清除為網域擁有權驗證程序手動新增的任何 Route 53 DNS 記錄。 | 應用程式開發人員 | 

## 疑難排解
<a name="implement-path-based-api-versioning-by-using-custom-domains-troubleshooting"></a>


| 問題 | 解決方案 | 
| --- | --- | 
| 部署`CustomDomainRouterStack`因為無法驗證憑證而逾時。 | 請確定您已新增適當的 DNS 驗證 CNAME 記錄，如先前任務所述。在新增 DNS **驗證**記錄之後，您的新憑證可能會繼續顯示等待驗證狀態長達 30 分鐘。如需詳細資訊，請參閱 AWS Certificate Manager 文件中的 [DNS 驗證](https://docs.aws.amazon.com/acm/latest/userguide/dns-validation.html)。 | 

## 相關資源
<a name="implement-path-based-api-versioning-by-using-custom-domains-resources"></a>
+ [使用 Amazon CloudFront 實作標頭型 API Gateway 版本控制](https://aws.amazon.com/blogs/compute/implementing-header-based-api-gateway-versioning-with-amazon-cloudfront/) – 此 AWS 運算部落格文章提供標頭型版本控制策略，以替代此模式中概述的路徑型版本控制策略。
+ [AWS CDK 研討會](https://cdkworkshop.com/20-typescript.html) – 此簡介研討會著重於 AWS 使用 在 上建置和部署應用程式 AWS Cloud Development Kit (AWS CDK)。此研討會支援 Go、Python 和 TypeScript。

## 其他資訊
<a name="implement-path-based-api-versioning-by-using-custom-domains-additional"></a>

**使用 Bruno 測試您的 API**

我們建議您使用開放原始碼 API 測試工具 [Bruno](https://www.usebruno.com/)，來驗證範例應用程式的路徑型路由是否正常運作。此模式提供範例集合，以協助測試您的範例 API。

若要叫用和測試您的 API，請使用下列步驟：

1. [安裝 Bruno。](https://www.usebruno.com/downloads)

1. 開啟 Bruno。

1. 在此模式的[程式碼儲存庫](https://github.com/aws-samples/path-based-versioning-with-api-gateway)中，選取 **Bruno/Sample-API-Gateway-Custom-Domain-Versioning**，然後開啟集合。

1. 若要查看使用者介面 (UI) 右上角**的環境**下拉式清單，請選取集合中的任何請求。

1. 在**環境**下拉式清單中，選取**設定**。

1. 將 `REPLACE_ME_WITH_YOUR_DOMAIN`值取代為您的自訂網域。

1. 選擇**儲存**，然後關閉**組態**區段。

1. 針對**沙盒環境**，** **確認已選取**作用中**選項。

1. 使用所選請求的 **->** 按鈕調用您的 API。

1. 請注意，與 V1 中如何處理驗證 （傳遞非數值）。 V2

若要查看範例 API 呼叫的螢幕擷取畫面，以及 V1 和 V2 驗證的比較，請參閱此模式[程式碼儲存庫](https://github.com/aws-samples/path-based-versioning-with-api-gateway)中的測試`README.md`檔案中**的範例 API**。