

# 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 服务** 

 将 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 版本控制。在添加可以配置为可选字段的字段时，或者为必填字段添加默认值时，扩展 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)
+ [ 微服务利弊权衡 ](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)
+ [ 从 Amazon API Gateway 到使用 OpenAPI 的 Amazon DynamoDB CRUD 应用程序 ](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/)