

# 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 のサービス** 

 [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 スキーマを定義して設定する、マネージド [GraphQL](https://graphql.org/) エンドポイントです。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 Serverless Application Model](https://aws.amazon.com/serverless/sam/) や [AWS Cloud Development Kit (AWS CDK)](https://aws.amazon.com/cdk/) などのコードツールとしての AWS インフラストラクチャと統合できます。
  +  [API 定義をエクスポートすると](https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-export-api.html)、API テストツールとの統合が簡素化され、サービス利用者に統合仕様が提供されます。
+  AWS AppSync で [GraphQL スキーマファイルを定義して](https://docs.aws.amazon.com/appsync/latest/devguide/designing-your-schema.html)、GraphQL API を定義して管理し、コントラクトインターフェイスを生成して、複雑な REST モデル、複数のデータベーステーブル、またはレガシー サービスとのやり取りを簡素化できます。
+  AWS AppSync と統合された [AWS Amplify](https://aws.amazon.com/amplify/) プロジェクトは、アプリケーションで使用するための厳密に型指定された JavaScript クエリファイルと、[Amazon DynamoDB](https://aws.amazon.com/dynamodb/) テーブル用の AWS AppSync GraphQL クライアントライブラリを生成します。
+  Amazon EventBridge からサービスイベントを利用する場合、イベントは、スキーマレジストリに既に存在するスキーマや OpenAPI 仕様で定義したスキーマに従います。レジストリでスキーマを定義すると、スキーマ契約からクライアントバインディングを生成して、コードをイベントと統合することもできます。
+  API の拡張またはバージョニング。オプションフィールドまたは必須フィールドのデフォルト値で構成できるフィールドを追加する場合、API を拡張する方が簡単なオプションです。
  +  REST や GraphQL などのプロトコルの JSON ベースの契約は、契約の拡張に適しています。
  +  SOAP のようなプロトコルの XML ベースの契約をサービスコンシューマーとテストして、契約拡張の可能性を判断する必要があります。
+  API をバージョニングするときは、ロジックを単一のコードベースで管理できるように、ファサードを使用してバージョンをサポートするプロキシバージョニングの実装を検討してください。
  +  API Gateway を使用すると、[リクエストとレスポンスのマッピング](https://docs.aws.amazon.com/apigateway/latest/developerguide/request-response-data-mappings.html#transforming-request-response-body)を使用して、新しいフィールドにデフォルト値を提供したり、リクエストまたはレスポンスから削除されたフィールドを削除したりするファサードを確立し、契約の変更の吸収を簡素化できます。このアプローチにより、基盤となるサービスが単一のコードベースを維持できます。

## リソース
<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)
+ [ 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 仕様](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 to Amazon DynamoDB CRUD application using OpenAPI](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)

 **関連動画:** 
+ [ 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/)