一般的なエラーを解決するために、API Gateway REST API を Amazon SQS と統合する方法を教えてください。
Amazon API Gateway REST API を Amazon Simple Queue Service (Amazon SQS) と統合したいと考えています。また、統合エラーのトラブルシューティングもしたいと考えています。
解決策
API ゲートウェイ REST API を Amazon SQS と統合するには、AWS クエリプロトコルまたは AWS JSON プロトコルのいずれかを使用します。
API Gateway REST API を Amazon SQS と統合するには、AWS クエリプロトコルを使用することができます。
次の手順を実行します。
-
AWS のサービス用の AWS Identity and Access Management (IAM) ロールを作成します。
注: [サービスまたはユースケース] で [API Gateway] を選択します。 -
API から Amazon SQS にメッセージを発行できるようにするには、SendMessage アクセス権限を持つ次の Amazon SQS ポリシーを添付してください。
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Resource": [ "arn:aws:sqs:example-region:example-account-id:example-sqs-queue-name" ], "Action": [ "sqs:SendMessage" ] } ] }注: example-region を実際の AWS リージョンに、** example-account-id** を実際の AWS アカウント ID に、example-sqs-queue-name を実際の SQS キュー名に置き換えます。
-
API Gateway コンソールで、REST API 用の Amazon SQS 統合を作成します。
-
REST API リソースまたは REST API メソッドを作成します。
[リソース] ページで [メソッドの作成] を選択します。
メソッドタイプで POST を選択します。
[統合タイプ] では、[AWS のサービス] を選択します。
[AWS リージョン]で、ご利用のリージョンを選択します。
[AWS サービス] で [Simple Queue Service (SQS)] を選択します。
(オプション) [AWS サブドメイン] に、AWS のサービスで使用するサブドメインを入力します。サブドメインが使用可能かどうかを確認するには、サービスのドキュメントを参照してください。Amazon SQS のサンプルセットアップでは、これは空欄のままにします。
[HTTP メソッド]で [POST] を選択します。
[アクションの種類] で [パス上書きを使用する] を選択します。
[パス上書き (省略可能)] には、アカウント ID と SQS キュー名を example-account-id/example-sqs-queue-name の形式で入力します。例: 1234567890/MySQSStandardQueue
[実行ロール] に IAM ロールの ARN を入力します。
[統合タイムアウト] で、セットアップのオプションを選択します。
REST API 統合情報の入力を続けます。
[メソッドを作成] を選択します。
POST メソッドの [統合リクエスト] を選択します。
[編集] を選択します。
[リクエスト本文のパススルー] では、要件に合ったオプションを選択します。
[URL リクエストヘッダーのパラメータ] を展開します。
[リクエストヘッダーのパラメータを追加] を選択します。
[名前] に content-type と入力します。
[マップ元] に application/x-www-form-urlencoded と入力します。
マッピングテンプレートを展開します。
[マッピングテンプレートを追加] を選択します。
[コンテンツタイプ] に、application/json と入力します。
テンプレートには、Action=SendMessage&MessageBody=$input.body と入力してから、[保存] を選択します。 -
API Gateway に次のリクエストを送信して、セットアップをテストします。
curl --location --request POST 'https://example-api-id.execute-api.example-region.amazonaws.com/example-stage/example-resource' \ --header 'Content-Type: application/json' \ --data-raw '{ "message": "Hello World" }'注: 実際のものでそれぞれ、example-api-id を API ID に、example-region をリージョンに、example-stage をテストステージ名に、example-resource をリソース名に置き換えます。
統合が成功した場合の応答例:{ "SendMessageResponse": { "ResponseMetadata": { "RequestId": "f879fb11-e736-52c0-bd29-a0f2d09ad90d" }, "SendMessageResult": { "MD5OfMessageAttributes": null, "MD5OfMessageBody": "3fc759ac1733366f98ec4270c788fcd1", "MD5OfMessageSystemAttributes": null, "MessageId": "4c360c3c-08f4-4392-bc14-8b0c88e314a2", "SequenceNumber": null } } }
API Gateway REST API を Amazon SQS と統合するには、AWS JSON プロトコルを使用することができます。
次の手順を実行します。
-
AWS のサービスの IAM ロールを作成します。
注: [サービスまたはユースケース] で [API Gateway] を選択します。 -
API から Amazon SQS にメッセージを発行できるようにするには、SendMessage アクセス権限を持つ次の Amazon SQS ポリシーを添付してください。
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Resource": [ "arn:aws:sqs:example-region:example-account-id:example-sqs-queue-name" ], "Action": [ "sqs:SendMessage" ] } ] }注: example-region を実際の AWS リージョンに、** example-account-id** を実際の AWS アカウント ID に、example-sqs-queue-name を実際の SQS キュー名に置き換えます。
-
API Gateway コンソールで、REST API 用の Amazon SQS 統合を作成します。
-
REST API リソースまたは REST API メソッドを作成します。
[リソース] ページで [メソッドの作成] を選択します。
[メソッドタイプ] で [POST] を選択します。
[統合タイプ] では、[AWS のサービス] を選択します。
[AWS リージョン]で、ご利用のリージョンを選択します。
[AWS サービス] で [Simple Queue Service (SQS)] を選択します。
[AWS サブドメイン] は空欄のままにします。これは、AWS サービスが使用するサブドメインを入力するオプションのパラメータです。サブドメインが使用可能かどうかを確認するには、サービスのドキュメントを参照してください。
[HTTP メソッド]で [POST] を選択します。
[アクションの種類] で [パス上書きを使用する] を選択します。
[パスのオーバーライド] に、文字 / を入力します。
[実行ロール] に IAM ロールの ARN を入力します。
[デフォルトタイムアウト] でセットアップに応じたオプションを選択します。
HTTP リクエストヘッダーを展開します。
[ヘッダーを追加] を選択します。
[名前] に content-type と入力します。
[ヘッダーを追加] を選択します。
[名前] に X-Amz-Target と入力します。
[メソッドを作成] を選択します。
POST メソッドの [統合リクエスト] を選択します。
[編集] を選択します。
[リクエスト本文のパススルー] は、デフォルトオプションである [テンプレートがリクエストの content-type ヘッダーと一致しない場合] から変更しないでください。
[URL リクエストヘッダーのパラメータ] を展開します。
[リクエストヘッダーのパラメータを追加] を選択します。
[名前] に content-type と入力します。
[マッピング元] で method.request.header.Content-Type と入力します。
[リクエストヘッダーのパラメータを追加] を選択します。
[名前] に X-Amz-Target と入力します。
[マッピング元] で method.request.header.X-Amz-Target と入力します。
[保存] を選択します。 -
API Gateway に次のリクエストを送信して、セットアップをテストします。
curl --location --request POST 'https://example-api-id.execute-api.example-region.amazonaws.com/example-stage/example-resource' \ --header 'Content-Type:application/x-amz-json-1.0' \ --header 'X-Amz-Target:AmazonSQS.SendMessage' \ --data-raw '{ "QueueUrl": "https://sqs.<region>.<domain>/<awsAccountId>/<queueName>/", "MessageBody": "This is a test message" }'注: 実際のものでそれぞれ、example-api-id を API ID に、example-region をリージョンに、example-stage をテストステージ名に、example-resource をリソース名に置き換えます。QueueUrl の値は、Amazon SQS キューの詳細に記載されています。
統合が成功した場合の応答例:
{"MD5OfMessageBody":"fafb00f5732ab283681e124bf8747ed1","MessageId":"b5aef1f3-af31-49f2-9973-6f802f7753e6"}
注: 同じ API コールでも、AWS JSON プロトコルから想定される応答は、AWS クエリプロトコルとは異なります。
一般的な SQS エラーの解決
一般的な Amazon SQS エラーを解決するには、表示されたエラーメッセージに対応する以下のトラブルシューティング手順に従ってください。
"UnknownOperationException" エラー
"UnknownOperationException" エラーは、AWS クエリプロトコルおよび AWS JSON プロトコルで発生する場合があります。
AWS クエリプロトコルを使用している場合、統合リクエストの HTTP ヘッダーで Content-Type を application/x-www-form-urlencoded に設定していないときにこのエラーが発生します。このエラーは、統合リクエストのマッピングテンプレートに SendMessage アクションを追加していない場合にも発生します。このエラーを解決するには、Content-Type の形式が適切であることを確認し、SendMessage アクションをマッピングテンプレートに含めます。
AWS JSON プロトコルを使用している場合、Content-Type と X-Amz-Target ヘッダーを送信していないか、正しく設定していない場合に、このエラーが発生します。このエラーを解決するには、Content-Type ヘッダーを "application/x-amz-json-1.0" に設定し、X-Amz-Target ヘッダーを AmazonSQS.{SQS-Action} に設定したうえで、両ヘッダーをリクエストに含めます。
"AccessDenied" エラー
"AccessDenied" エラーは、AWS クエリプロトコルおよび AWS JSON プロトコルで発生する可能性があります。
API 統合の実行ロールに、SQS キューにメッセージを送信するための sqs:SendMessage 権限が設定されていない場合に、このエラーが発生します。
このエラーは、AWS クエリプロトコルを使用しており、サポートされていない特殊文字をリクエスト本文のペイロード文字列に渡した場合にも発生します。このエラーを回避するには、特殊文字をエンコードする必要があります。マッピングテンプレートに $util.urlEncode() 関数を追加し、リクエスト本文を文字列からエンコードされた形式に変換します。マッピングテンプレートの例を次に示します。
Action=SendMessage&MessageBody=$util.urlEncode($input.body)
Amazon SQS 先入れ先出し (FIFO) キューを使用する場合は、必ず MessageGroupId または MessageDeduplicationId 属性のいずれかを含めてください。FIFO マッピングテンプレートの例を次に示します。
Action=SendMessage&MessageBody=$util.urlEncode($input.body)&MessageGroupId=$your-msg-group-id&MessageDeduplicationId=$your-msg-dedup-id
注: your-msg-group-id を実際のメッセージグループ ID に、your-msg-dedup-id を実際のメッセージ重複排除 ID に置き換えてください。
次の例には、SQS キューにメッセージを送信するために必要なアクセス許可が含まれています。
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Resource": [ "arn:aws:sqs:example-region:example-account-id:example-sqs-queue-name" ], "Action": [ "sqs:SendMessage" ] } ] }
注: 実際のものでそれぞれ、example-region をリージョンに、example-account-id をアカウント ID に、example-sqs-queue-name を SQS キュー名に置き換えます。
"KMS.AccessDeniedException" エラー
"KMS.AccessDeniedException" エラーは、AWS クエリプロトコルおよび AWS JSON プロトコルから発生する可能性があります。
このエラーは、API 統合実行ロールが AWS Key Management Service (AWS KMS) を介して操作を実行できない場合に発生します。このエラーを解決するには、Amazon SQS サーバー側の暗号化キューにアタッチされている AWS KMS キーに対して操作を実行するためのアクセス許可を設定します。
次の例には、SQS キューにアタッチされている KMS キーを操作するために必要なアクセス許可が含まれています。
{ "Sid": "Allow use of the key", "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::example-account-id:role/example-api-gw-integration-execution-role" }, "Action": [ "kms:Encrypt", "kms:GenerateDataKey*", "kms:Decrypt" ], "Resource": "*" }
注: 実際のものでそれぞれ、example-account-id をアカウント ID に、example-api-gw-integration-execution-role を実行ロール名に置き換えます。
"MalformedQueryString" エラー
"MalformedQueryString" エラーは、AWS クエリプロトコルと AWS JSON プロトコルの両方から発生する可能性があります。
このエラーは、リクエスト本文のペイロード文字列に特殊文字が含まれている場合に発生します。マッピングテンプレートに $util.urlEncode() 関数を追加し、リクエスト本文を文字列からエンコードされた形式に変換します。マッピングテンプレートの例を次に示します。
Action=SendMessage&MessageBody=$util.urlEncode($input.body)
"SignatureDoesNotMatch" エラー
AWS クエリプロトコルの使用時に、"SignatureDoesNotMatch" エラーが発生する場合があります。
このエラーは、統合リクエストの HTTP メソッドが POST ではなく GET に設定されている場合に発生します。このエラーを解決するには、HTTP メソッドを POST に設定します。
"InvalidAddress" エラー
AWS JSON プロトコルの使用時に、"InvalidAddress" エラーが発生する場合があります。
このエラーは、本文ペイロードの SQS キュー URL が正しくない場合に発生します。このエラーを解決するには、API コールの対象となる SQS キューのキュー URL を確認します。
"SerializationException" エラー
"SerializationException" エラーは、AWS JSON プロトコルの使用時に発生する場合があります。
このエラーは、本文ペイロードが有効な JSON でない場合に発生します。たとえば、JSON にカンマが抜けている、余分なカンマがある、中括弧が抜けている、余分な中括弧がある場合が該当します。このエラーを解決するには、JSON を有効な形式に変更してください。
"MissingRequiredParameterException" エラー
"MissingRequiredParameterException" エラーは、AWS JSON プロトコルの使用時に発生する場合があります。
このエラーは、ボディペイロードに必須パラメータを 1 つ以上含めない場合に発生します。必要なパラメータは API 呼び出しによって異なります。たとえば、このエラーは SendMessage API コールに MessageBody パラメータが指定されていない場合に発生します。必要なパラメータと構文については、「SQS API のリファレンス」を確認してください。

