

# REL03-BP03 根据 API 提供服务合同
<a name="rel_service_architecture_api_contracts"></a>

服务合同是 API 生产者与使用者之间的书面协议，采用机器可读的 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 服务** 

 将包括 [Amazon API Gateway](https://aws.amazon.com/api-gateway/)、[AWS AppSync](https://aws.amazon.com/appsync/) 和 [Amazon EventBridge](https://aws.amazon.com/eventbridge/) 在内的 AWS 服务整合到架构中，以便在应用程序中使用 API 服务合同。Amazon API Gateway 有助于直接与原生 AWS 服务和其他网络服务集成。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 测试工具的集成，并为服务使用者提供集成规范。
+  您可以通过[定义 GraphQL 架构](https://docs.aws.amazon.com/appsync/latest/devguide/designing-your-schema.html)文件，使用 AWS AppSync 来定义和管理 GraphQL API，从而生成合同接口，并简化与复杂 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 版本控制。在添加可以配置为可选字段的字段时，或者为必填字段添加默认值时，扩展 API 是一种相对比较简单的选项。
  +  对于 REST 和 GraphQL 等协议，基于 JSON 的合同可能非常适合合同扩展。
  +  对于 SOAP 等协议，基于 XML 的合同应与服务使用者一起进行测试，来确定合同扩展的可行性。
+  对 API 进行版本控制时，可以考虑实施代理版本控制，其中使用 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)
+ [Microservice Trade-Offs](https://martinfowler.com/articles/microservice-trade-offs.html)
+ [Microservices – a definition of this new architectural term](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-Specification](https://github.com/OAI/OpenAPI-Specification)
+ [GraphQL: Schemas and Types](https://graphql.org/learn/schema/)
+ [Amazon EventBridge code bindings](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)
+ [Amazon API Gateway to Amazon DynamoDB CRUD application using OpenAPI](https://serverlessland.com/patterns/apigw-ddb-openapi-crud?ref=search)
+ [Modern application integration patterns in a serverless age: API Gateway Service Integration](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)
+ [Implementing header-based API Gateway versioning with Amazon CloudFront](https://aws.amazon.com/blogs/compute/implementing-header-based-api-gateway-versioning-with-amazon-cloudfront/)
+ [AWS AppSync: Building a client application](https://docs.aws.amazon.com/appsync/latest/devguide/building-a-client-app.html#aws-appsync-building-a-client-app)

 **相关视频：**
+ [Using OpenAPI in AWS SAM to manage 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/)