

# REL03-BP03 每個 API 都提供服務合約
<a name="rel_service_architecture_api_contracts"></a>

服務合約是 API 生產者與取用者之間的記錄協議，載明於機器可讀取的 API 定義中。合約版本控制策略可讓取用者繼續使用現有的 API，並在準備好時將應用程式遷移至更新的 API。只要遵守合約，就隨時可執行生產者部署。服務團隊可以使用自己選擇的技術堆疊，以滿足 API 合約要求。

 **預期成果：** 

 **常見的反模式：** 以服務導向或微型服務架構建置的應用程式能夠獨立運作，同時具有整合的執行期相依性。當雙方遵循共同的 API 合約時，部署至 API 取用者或生產者的變更不會中斷整體系統的穩定性。透過服務 API 進行通訊的元件可以執行獨立運作的版本、升級至執行期相依性，或容錯移轉至災難復原 (DR) 站台，且彼此幾乎沒有影響或完全沒有影響。此外，離散服務能夠獨立擴展而滿足資源需求，不需要其他服務一起擴展。 
+  建立不具強型別結構描述的服務 API。這會產生無法用來產生 API 繫結的 API，以及無法以程式設計方式驗證的承載。 
+  未採用版本控制策略，會迫使 API 取用者更新和發行，或在服務合約發展時失敗。 
+  錯誤訊息會透露基礎服務實作的詳細資訊，而不是說明領域環境和語言中的整合失敗。 
+  未使用 API 合約來開發測試案例和模擬 API 實作，以允許單獨測試服務元件。 

 **建立此最佳實務的優勢：** 由透過 API 服務合約進行通訊的元件組成的分散式系統可提升可靠性。開發人員可在開發過程中及早發現潛在問題，並在編譯期間進行類型檢查，以確認請求和回應遵循 API 合約，且必要欄位存在。API 合約為 API 提供了清晰的自我記錄介面，並在不同的系統和程式設計語言之間提供了更好的互通性。 

 **未建立此最佳實務時的曝險等級：** 中 

## 實作指引
<a name="implementation-guidance"></a>

 在識別商業領域並確認工作負載區隔後，即可開發服務 API。首先，請定義機器可讀取的 API 服務合約，然後實作 API 版本控制策略。準備好透過 REST、GraphQL 等一般通訊協定或非同步事件來整合服務後，您可以將 AWS 服務併入您的架構中，以便將元件與強型別 API 合約整合。 

 **服務 API 合約的 AWS 服務** 

 將 AWS 服務 (包括 [Amazon API Gateway](https://aws.amazon.com/api-gateway/)、[AWS AppSync](https://aws.amazon.com/appsync/)和 [Amazon EventBridge](https://aws.amazon.com/eventbridge/) ) 併入您的架構中，以在您的應用程式中使用 API 服務合約。Amazon API Gateway 可協助您直接與原生 AWS 服務和其他 Web 服務整合。API Gateway 支援 [OpenAPI 規格](https://github.com/OAI/OpenAPI-Specification) 和版本控制。AWS AppSync 是一個受管 [GraphQL](https://graphql.org/) 端點，可藉由定義 GraphQL 結構描述來設定，用以定義查詢、變動和訂閱的服務介面。Amazon EventBridge 使用事件結構描述來定義事件及產生事件的程式碼繫結。 

## 實作步驟
<a name="implementation-steps"></a>
+  首先，為您的 API 定義合約。合約會說明 API 的功能，並定義強型別的資料物件和欄位，以用於 API 輸入和輸出。 
+  在 API Gateway 中設定 API 時，您可以為端點匯入和匯出 OpenAPI 規格。 
  +  [匯入 OpenAPI 定義](https://docs.aws.amazon.com/apigateway/latest/developerguide/import-edge-optimized-api.html) 可簡化 API 的建立，並且可以與 AWS 基礎設施即程式碼工具整合，例如 [AWS Serverless Application Model](https://aws.amazon.com/serverless/sam/) 和 [AWS Cloud Development Kit (AWS CDK)](https://aws.amazon.com/cdk/)。 
  +  [匯出 API 定義](https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-export-api.html) 可簡化與 API 測試工具的整合，並為服務取用者提供整合規格。 
+  您可以透過 AWS AppSync 來定義和管理 GraphQL API，方法是 [定義 GraphQL 結構描述](https://docs.aws.amazon.com/appsync/latest/devguide/designing-your-schema.html) 檔案以產生合約介面，並簡化與複雜 REST 模型、多個資料庫資料表或舊版服務的互動。 
+  [AWS Amplify](https://aws.amazon.com/amplify/) 專案 (與 AWS AppSync 整合) 會產生強型別 JavaScript 查詢檔案以供您的應用程式使用，並產生 AWS AppSync GraphQL 用戶端程式庫用於 [Amazon DynamoDB](https://aws.amazon.com/dynamodb/) 資料表。 
+  當您從 Amazon EventBridge 中取用服務事件時，事件會遵循結構描述登錄中已存在的結構描述，或您使用 OpenAPI 規格定義的結構描述。使用登錄中定義的結構描述時，您也可以從結構描述合約產生用戶端繫結，以將程式碼與事件整合。 
+  擴充您的 API 或對其進行版本控制。在新增可使用選用欄位或必要欄位的預設值來設定的欄位時，擴充 API 是較簡單的選項。 
  +  REST 和 GraphQL 等通訊協定的 JSON 型合約可能非常適合進行合約展延。 
  +  SOAP 等通訊協定的 XML 型合約應進行服務取用者的測試，以確認合約展延的可行性。 
+  在對 API 進行版本控制時，請考慮實作 Proxy 版本控制，使用 Facade 來支援版本，以便在單一程式碼基底中維護邏輯。 
  +  透過 API Gateway，您可以使用 [請求和回應對應](https://docs.aws.amazon.com/apigateway/latest/developerguide/request-response-data-mappings.html#transforming-request-response-body) 建立 Facade 以提供新欄位的預設值，或從請求或回應中去除已移除的欄位，以簡化因應合約變更的工作。透過此方法，基礎服務可以維護單一程式碼基底。 

## 資源
<a name="resources"></a>

 **相關的最佳實務：** 
+  [REL03-BP01 選擇如何劃分工作負載](rel_service_architecture_monolith_soa_microservice.md) 
+  [REL03-BP02 建置專注於特定業務領域和功能的服務](rel_service_architecture_business_domains.md) 
+  [REL04-BP02 實作鬆耦合相依性](rel_prevent_interaction_failure_loosely_coupled_system.md) 
+  [REL05-BP03 控制和限制重試呼叫](rel_mitigate_interaction_failure_limit_retries.md) 
+  [REL05-BP05 設定用戶端逾時](rel_mitigate_interaction_failure_client_timeouts.md) 

 **相關文件：** 
+ [ 什麼是 API (應用程式設計介面)？ ](https://aws.amazon.com/what-is/api/)
+ [ 實作 AWS 上的微型服務 ](https://docs.aws.amazon.com/whitepapers/latest/microservices-on-aws/microservices-on-aws.html)
+ [ 微型服務權衡 ](https://martinfowler.com/articles/microservice-trade-offs.html)
+ [ 微型服務 - 此新架構術語的定義 ](https://www.martinfowler.com/articles/microservices.html)
+ [AWS 上的微型服務 ](https://aws.amazon.com/microservices/)
+ [ 使用 OpenAPI 的 API Gateway 延伸 ](https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-swagger-extensions.html)
+ [ OpenAPI 規格 ](https://github.com/OAI/OpenAPI-Specification)
+ [ GraphQL：結構描述和類型 ](https:/graphql.org/learn/schema)
+ [ Amazon EventBridge 程式碼繫結 ](https://docs.aws.amazon.com/eventbridge/latest/userguide/eb-schema-code-bindings.html)

 **相關範例：** 
+ [ Amazon API Gateway：使用 OpenAPI 設定 REST API ](https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-import-api.html)
+ [ 使用 OpenAPI 設定 Amazon DynamoDB CRUD 應用程式的 Amazon API Gateway ](https://serverlessland.com/patterns/apigw-ddb-openapi-crud?ref=search)
+ [ 無伺服器時代的現代化應用程式整合模式：API Gateway 服務整合 ](https://catalog.us-east-1.prod.workshops.aws/workshops/be7e1ee7-b91f-493d-93b0-8f7c5b002479/en-US/labs/asynchronous-request-response-poll/api-gateway-service-integration)
+ [ 使用 Amazon CloudFront 實作標題型 API Gateway 版本控制 ](https://aws.amazon.com/blogs/compute/implementing-header-based-api-gateway-versioning-with-amazon-cloudfront/)
+ [AWS AppSync：建置用戶端應用程式 ](https://docs.aws.amazon.com/appsync/latest/devguide/building-a-client-app.html#aws-appsync-building-a-client-app)

 **相關影片：** 
+ [ 在 AWS SAM 中使用 OpenAPI 管理 API Gateway ](https://www.youtube.com/watch?v=fet3bh0QA80)

 **相關工具：** 
+ [ Amazon API Gateway ](https://aws.amazon.com/api-gateway/)
+ [AWS AppSync](https://aws.amazon.com/appsync/)
+ [ Amazon EventBridge ](https://aws.amazon.com/eventbridge/)