

翻訳は機械翻訳により提供されています。提供された翻訳内容と英語版の間で齟齬、不一致または矛盾がある場合、英語版が優先します。

# Amazon API Gateway と Amazon DynamoDB Streams を使用してイベントを非同期的に処理する
<a name="processing-events-asynchronously-with-amazon-api-gateway-and-amazon-dynamodb-streams"></a>

*Amazon Web Services、Andrea Meroni、Mariem Kthiri、Nadim Majed、Alessandro Trisolini、Michael Wallner*

## 概要
<a name="processing-events-asynchronously-with-amazon-api-gateway-and-amazon-dynamodb-streams-summary"></a>

[Amazon API Gateway](https://docs.aws.amazon.com/apigateway/latest/developerguide/welcome.html) は、開発者が API を作成、配布、保守、監視、保護するために規模に関係なく使用できるフルマネージドサービスです。最大で数十万個の同時 API コールの受け入れと処理に伴うすべてのタスクを取り扱います。

API Gateway の重要なサービスクォータは、統合タイムアウトです。このタイムアウトは、バックエンドサービスがレスポンスを返さなければならない最大時間で、その後は REST API がエラーを返します。29 秒のハードリミットは、同期ワークロードでは一般的に許容されます。ただし、この制限は、非同期ワークロードで API Gateway を使用するデベロッパーにとっての課題です。

このパターンは、API Gateway、Amazon DynamoDB Streams、および を使用してイベントを非同期的に処理するためのアーキテクチャの例を示しています AWS Lambda。このアーキテクチャは、同じ入力パラメータを使用した並列処理ジョブの実行をサポートし、インターフェイスとして基本的な REST API を使用します。この例では、Lambda をバックエンドとして使用すると、ジョブの期間は 15 分に制限されます。この制限を回避するには、代替サービスを使用して受信イベント (例:) を処理します AWS Fargate。

[Projen](https://pypi.org/project/projen/) は、ローカル開発環境をセットアップし AWS アカウント、[AWS Cloud Development Kit (AWS CDK) Toolkit](https://docs.aws.amazon.com/cdk/v2/guide/cli.html)、[Docker](https://docs.docker.com/get-docker/)、[Node.js](https://nodejs.org/en/download/) と組み合わせてサンプルアーキテクチャをターゲットにデプロイするために使用されます。Projen は、[事前コミット](https://pre-commit.com/)と、コードの品質保証、セキュリティスキャン、ユニットテストに使用されるツールを使用して、[Python](https://www.python.org/downloads/) 仮想環境を自動でセットアップします。詳しくは「[ツール](#processing-events-asynchronously-with-amazon-api-gateway-and-amazon-dynamodb-streams-tools)」セクションをご確認ください。

## 前提条件と制限事項
<a name="processing-events-asynchronously-with-amazon-api-gateway-and-amazon-dynamodb-streams-prereqs"></a>

**前提条件**
+ アクティブな AWS アカウント
+ ワークステーションにインストールされている以下のツール:
  + [AWS Cloud Development Kit (AWS CDK) Toolkit](https://docs.aws.amazon.com/cdk/v2/guide/cli.html) バージョン 2.85.0 以降
  + [Docker](https://docs.docker.com/get-docker/) バージョン 20.10.21 以降
  + [Node.js](https://nodejs.org/en/download/) バージョン 18 以降
  + [Projen](https://pypi.org/project/projen/) バージョン 0.71.111 以降
  + [Python](https://www.python.org/downloads/) バージョン 3.9.16 以降

**制限事項**
+ スロットリングを避けるため、DynamoDB Streams の推奨最大リーダー数は 2 です。
+ ジョブの最大ランタイムは、Lambda 関数の最大ランタイム (15 分) によって制限されます。
+ 同時ジョブリクエストの最大数は、Lambda 関数の予約済み同時実行数によって制限されます。

## アーキテクチャ
<a name="processing-events-asynchronously-with-amazon-api-gateway-and-amazon-dynamodb-streams-architecture"></a>

**アーキテクチャ**

次の図は、Amazon EventBridge イベントアーカイブに保存されたイベントと、DynamoDB Streams およびイベント処理とエラー処理の Lambda 関数とのジョブ API の相互作用を示しています。

![\[アーキテクチャとプロセスの図 (図の後にステップがリストされています)。\]](http://docs.aws.amazon.com/ja_jp/prescriptive-guidance/latest/patterns/images/pattern-img/68a46501-16e5-48e4-99c6-fc67a8b4133a/images/29fe6982-ad81-4099-9c65-08b17c96e78f.png)


一般的なワークフローには、以下のステップが含まれます。

1.  AWS Identity and Access Management (IAM) に対して認証し、セキュリティ認証情報を取得します。

1. HTTP `POST` リクエストを `/jobs` ジョブ API エンドポイントに送信し、リクエスト本文のジョブパラメータを指定します。

1. ジョブ API は、ジョブ識別子を含む HTTP レスポンスを返します。

1. ジョブ API は、ジョブパラメータを `jobs_table` Amazon DynamoDB テーブルに置きます。

1. `jobs_table` DynamoDB テーブルの DynamoDB ストリームは、イベント処理 Lambda 関数を呼び出します。

1. イベント処理 Lambda 関数はイベントを処理し、ジョブ結果を DynamoDB `jobs_table` テーブルに置きします。一貫した結果を確保するために、イベント処理関数は[楽観的ロック](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/DynamoDBMapper.OptimisticLocking.html)メカニズムを実装します。

1. ステップ 3 の `/jobs/{jobId}` ジョブ識別子を `{jobId}` として、ジョブ API エンドポイントに HTTP `GET` リクエストを送信します。

1. ジョブ API は DynamoDB `jobs_table` テーブルにクエリを実行してジョブ結果を取得します。

1. ジョブ API は、ジョブ結果を含む HTTP レスポンスを返します。

1. イベント処理が失敗した場合、イベント処理関数のソースマッピングは、エラー処理を行う Amazon Simple Notiﬁcation Service (Amazon SNS) トピックにイベントを送信します。

1. エラー処理 SNS トピックは、イベントをエラー処理関数に非同期的にプッシュします。

1. エラー処理関数は、DynamoDB `jobs_table` テーブルにジョブパラメータを置きます。

   ジョブ API エンドポイントに HTTP `GET` リクエストを送信することで、`/jobs/{jobId}` ジョブパラメータを取得できます。

1. エラー処理が失敗した場合、エラー処理関数はイベントを Amazon EventBridge アーカイブに送信します。

   EventBridge を使用して、アーカイブされたイベントを再生できます。

## ツール
<a name="processing-events-asynchronously-with-amazon-api-gateway-and-amazon-dynamodb-streams-tools"></a>

**AWS サービス**
+ [AWS Cloud Development Kit (AWS CDK)](https://docs.aws.amazon.com/cdk/v2/guide/home.html) は、AWS クラウドインフラストラクチャをコードで定義して割り当てるのに役立つソフトウェア開発フレームワークです。
+ [Amazon DynamoDB](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Introduction.html) は、フルマネージド NoSQL データベースサービスです。高速かつ予測可能でスケーラブルなパフォーマンスを提供します。
+ 「[Amazon EventBridge](https://docs.aws.amazon.com/eventbridge/latest/userguide/eb-what-is.html)」 は、アプリケーションをさまざまなソースのデータに接続するために支援するサーバーレスイベントバスサービスです。たとえば、AWS Lambda 関数、API 宛先を使用する HTTP 呼び出しエンドポイント、または他の AWS アカウントのイベントバスなどです。
+ [AWS Lambda](https://docs.aws.amazon.com/lambda/latest/dg/welcome.html) は、サーバーのプロビジョニングや管理を行うことなくコードを実行できるコンピューティングサービスです。必要に応じてコードを実行し、自動的にスケーリングするため、課金は実際に使用したコンピューティング時間に対してのみ発生します。
+ 「[Amazon Simple Notiﬁcation Service (Amazon SNS)](https://docs.aws.amazon.com/sns/latest/dg/welcome.html)」は、ウェブサーバーやメールアドレスなど、パブリッシャーとクライアント間のメッセージの交換を調整および管理するのに役立ちます。

**その他のツール**
+ [autopep8](https://github.com/hhatto/autopep8) は、Python Enhancement Proposal (PEP) 8 スタイルガイドに基づいて自動的に Python コードをフォーマットします。
+ [Bandit](https://bandit.readthedocs.io/en/latest/) は Python コードをスキャンして、一般的なセキュリティ問題を見つけます。
+ [Commitizen](https://commitizen-tools.github.io/commitizen/) は Git コミットチェッカーと `CHANGELOG` ジェネレーターです。
+ [cfn-lint](https://github.com/aws-cloudformation/cfn-lint) は linter AWS CloudFormation です
+ [Checkov](https://github.com/bridgecrewio/checkov) は、Infrastructure as Code (IaC) のセキュリティとコンプライアンスの設定ミスをチェックする静的コード分析ツールです。
+ [jq](https://stedolan.github.io/jq/download/) は JSON を構文解析するコマンドラインツールです。
+ [Postman](https://www.postman.com/) は API プラットフォームです。
+ [事前コミット](https://pre-commit.com/)は Git フックマネージャーです。
+ [Projen](https://github.com/projen/projen) はプロジェクトジェネレーターです。
+ 「[pytest](https://docs.pytest.org/en/7.2.x/index.html)」は、小さくて読みやすいテストを書くための Python フレームワークです。

**コードリポジトリ**

このアーキテクチャコードの例は、GitHub [Asynchronous Processing with API Gateway and DynamoDB Streams](https://github.com/aws-samples/asynchronous-event-processing-api-gateway-dynamodb-streams-cdk) リポジトリから取得できます。

## ベストプラクティス
<a name="processing-events-asynchronously-with-amazon-api-gateway-and-amazon-dynamodb-streams-best-practices"></a>
+ この例のアーキテクチャには、デプロイされたインフラストラクチャのモニタリングは含まれません。モニタリングが必要なユースケースの場合は、[CDK モニタリングコンストラクト](https://constructs.dev/packages/cdk-monitoring-constructs)または別のモニタリングソリューションの追加を評価します。
+ このアーキテクチャ例では、[IAM アクセス許可](https://docs.aws.amazon.com/apigateway/latest/developerguide/permissions.html)を使用して、ジョブ API へのアクセスを制御します。`JobsAPIInvokeRole` を引き受ける権限を持つユーザーは、ジョブ API を呼び出すことができます。そのため、アクセスコントロールメカニズムはバイナリです。より複雑な認可モデルが必要なユースケースの場合は、別の[アクセスコントロールメカニズム](https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-control-access-to-api.html)の使用を評価します。
+ ユーザーが `/jobs` ジョブ API エンドポイントに HTTP `POST` リクエストを送信すると、入力データは 2 つの異なるレベルで検証されます。
  + API Gateway は、最初の[リクエスト検証](https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-method-request-validation.html)を担当します。
  + イベント処理関数は、2 番目のリクエストを実行します。

    ユーザーが `/jobs/{jobId}` ジョブ API エンドポイントに対して HTTP `GET` リクエストを実行する場合、検証は実行されません。ユースケースで追加の入力検証とセキュリティレベルの向上が必要な場合は、 [AWS WAF を使用して API を保護します](https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-control-access-aws-waf.html)。
+ スロットリングを避けるために、[DynamoDB Streams ドキュメント](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Streams.html#Streams.Processing)では、ユーザーが同じストリームのシャードから 3 つ以上のコンシューマーで読み取ることを推奨していません。コンシューマーの数をスケールアウトするため、[Amazon Kinesis Data Streams ](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/kds.html)を使用することをお勧めします。
+ この例では、DynamoDB `jobs_table` テーブル内の項目の一貫した更新を確保するために、[楽観的ロック](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/DynamoDBMapper.OptimisticLocking.html)が使用されています。ユースケースの要件によっては、悲観的ロックなど、より信頼性の高いロックメカニズムを実装する必要がある場合があります。

## エピック
<a name="processing-events-asynchronously-with-amazon-api-gateway-and-amazon-dynamodb-streams-epics"></a>

### 環境をセットアップする
<a name="set-up-the-environment"></a>


| タスク | 説明 | 必要なスキル | 
| --- | --- | --- | 
| リポジトリのクローン作成 | リポジトリをローカルに複製するには、次のコマンドを実行します。<pre>git clone https://github.com/aws-samples/asynchronous-event-processing-api-gateway-dynamodb-streams-cdk.git</pre> | DevOps エンジニア | 
| プロジェクトを設定します。 | ディレクトリをリポジトリルートに変更し、[Projen](https://github.com/projen/projen) を使用して Python 仮想環境とすべてのツールを設定します。<pre>cd asynchronous-event-processing-api-gateway-api-gateway-dynamodb-streams-cdk<br />npx projen</pre> | DevOps エンジニア | 
| 事前コミットフックをインストールします。 | 事前コミットフックをインストールするには、以下を実行します。[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ja_jp/prescriptive-guidance/latest/patterns/processing-events-asynchronously-with-amazon-api-gateway-and-amazon-dynamodb-streams.html) | DevOps エンジニア | 

### サンプルアーキテクチャをデプロイする
<a name="deploy-the-example-architecture"></a>


| タスク | 説明 | 必要なスキル | 
| --- | --- | --- | 
| ブートストラップ AWS CDK。 | [AWS CDK](https://aws.amazon.com/cdk/) でブートストラップするには AWS アカウント、次のコマンドを実行します。<pre>AWS_PROFILE=$YOUR_AWS_PROFILE npx projen bootstrap</pre> | AWS DevOps | 
| サンプルアーキテクチャをデプロイします。 | にサンプルアーキテクチャをデプロイするには AWS アカウント、次のコマンドを実行します。<pre>AWS_PROFILE=$YOUR_AWS_PROFILE npx projen deploy</pre> | AWS DevOps | 

### アーキテクチャをテストする
<a name="test-the-architecture"></a>


| タスク | 説明 | 必要なスキル | 
| --- | --- | --- | 
| テストの前提条件をインストールします。 | [AWS Command Line Interface (AWS CLI)](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html)、[Postman](https://www.postman.com/downloads/)、[jq](https://jqlang.github.io/jq/) をワークステーションにインストールします。[Postman](https://www.postman.com/downloads/) を使用してこのサンプルアーキテクチャをテストすることをお勧めしますが、必須ではありません。代替の API テストツールを選択する場合は、[AWS 署名バージョン 4 認証](https://docs.aws.amazon.com/AmazonS3/latest/API/sig-v4-authenticating-requests.html)をサポートしていることを確認し、また、[REST API をエクスポート](https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-export-api.html)して検査できる公開 API エンドポイントを参照してください。 | DevOps エンジニア | 
| `JobsAPIInvokeRole` を引き受けます。 | `deploy` コマンドから出力された `JobsAPIInvokeRole` を[引き受け](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/sts/assume-role.html)ます。<pre>CREDENTIALS=$(AWS_PROFILE=$<YOUR_AWS_PROFILE> aws sts assume-role \<br />--no-cli-pager \<br />--role-arn $<JOBS_API_INVOKE_ROLE_ARN> \<br />--role-session-name JobsAPIInvoke)<br />export AWS_ACCESS_KEY_ID=$(cat $CREDENTIALS | jq ‘.Credentials’’.AccessKeyId’)<br />export AWS_SECRET_ACCESS_KEY=$(cat $CREDENTIALS | jq ‘.Credentials’’.SecretAccessKey’)<br />export AWS_SESSION_TOKEN==$(cat $CREDENTIALS | jq ‘.Credentials’’.SessionToken’)</pre> | AWS DevOps | 
| Postman を設定します。 | [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ja_jp/prescriptive-guidance/latest/patterns/processing-events-asynchronously-with-amazon-api-gateway-and-amazon-dynamodb-streams.html) | AWS DevOps | 
| サンプルアーキテクチャをテストします。 | サンプルアーキテクチャをテストするには、ジョブ API にリクエストを送信します。詳細については、[Postman ドキュメント](https://learning.postman.com/docs/getting-started/first-steps/sending-the-first-request/#send-an-api-request)を参照してください。 | DevOps エンジニア | 

## トラブルシューティング
<a name="processing-events-asynchronously-with-amazon-api-gateway-and-amazon-dynamodb-streams-troubleshooting"></a>


| 問題 | ソリューション | 
| --- | --- | 
| [Amazon CloudWatch Logs ロググループ](https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/WhatIsCloudWatchLogs.html) `/aws/apigateway/JobsAPIAccessLogs` が既に存在するため、サンプルアーキテクチャの破壊とその後の再デプロイは失敗します。 | [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ja_jp/prescriptive-guidance/latest/patterns/processing-events-asynchronously-with-amazon-api-gateway-and-amazon-dynamodb-streams.html) | 

## 関連リソース
<a name="processing-events-asynchronously-with-amazon-api-gateway-and-amazon-dynamodb-streams-resources"></a>
+ [API Gateway マッピングテンプレートとアクセスロギング変数リファレンス](https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-mapping-template-reference.html)
+ [DynamoDB Streams のデータキャプチャを変更する](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Streams.html)
+ [バージョン番号によるオプティミスティックロック](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/DynamoDBMapper.OptimisticLocking.html)
+ [Kinesis Data Streams を使用して DynamoDB への変更をキャプチャする](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/kds.html)