如何將 API Gateway REST API 與 Amazon SQS 予以整合,並解決常見錯誤?

5 分的閱讀內容
0

我要將 Amazon API Gateway REST API 與 Amazon Simple Queue Service (Amazon SQS) 予以整合,並對整合錯誤進行疑難排解。

解決方法

若要將 API Gateway REST API 與 Amazon SQS 整合,請選擇下列其中一種方法:

使用 AWS 查詢通訊協定

若要將 API Gateway REST API 與 Amazon SQS 整合,您可以使用 AWS 查詢通訊協定。為此,請完成下列步驟:

  1. 建立 SQS 佇列
  2. 建立 AWS Identity and Access Management (IAM) 角色,然後將 Amazon SQS 政策與 SendMessage 許可連接起來。這項政策可讓您將訊息從 API 發佈到 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 佇列名稱。

  1. 在 API Gateway 中建立 REST API
  2. API Gateway 主控台中,建立適用於 REST API 的 Amazon SQS 整合。
  3. 建立 REST API 資源或 REST API 方法
    資源畫面上,選擇建立方法
    針對方法類型,選擇 POST
    對於整合類型,請選擇 AWS 服務
    對於 AWS Region (AWS 區域),請選擇您的區域。
    對於 AWS Service (AWS 服務),請選擇 Simple Queue Service (SQS)
    (選用) 對於 AWS Subdomain (AWS 子網域),請輸入 AWS 服務使用的子網域。請檢查 AWS 服務的文件以確認子網域的可用性。對於 Amazon SQS 範例設定,請將其保留空白。
    對於 HTTP method (HTTP 方法),請選擇 POST
    對於 Action Type (動作類型),選擇 Use path override (使用路徑覆寫)。
    對於路徑覆寫 (選用),請以下列格式輸入您的帳戶 ID 和 SQS 佇列名稱:example-account-id/example-sqs-queue-name。例如: 1234567890/MySQSStandardQueue
    對於 Execution role (執行角色),請輸入 IAM 角色的 ARN。
    對於 Default Timeout (預設逾時),請選擇設定的選項。
    繼續輸入 REST API 整合資訊。
    選擇 POST 方法整合請求
    選擇編輯
    對於 Request body passthrough (請求內文傳遞),請選取適用於需求的選項。
    展開 URL 請求標頭參數
    選擇新增請求標頭參數
    對於名稱,請輸入 Content-Type
    對於映射來源,請輸入 'application/x-www-form-urlencoded'
    然後,展開映射範本
    選擇新增映射範本
    對於 Content-Type,請輸入 application/json
    對於範本,請輸入 Action=SendMessage&MessageBody=$input.body,然後選擇儲存
  4. 部署 REST API
  5. 若要測試設定,請將下列請求傳送至 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  
    }  
  }  
}

使用 AWS JSON 通訊協定

若要將 API Gateway REST API 與 Amazon SQS 整合,您可以使用 AWS JSON 通訊協定。為此,請完成下列步驟:

  1. 建立 SQS 佇列
  2. 建立 AWS IAM 角色,然後將 Amazon SQS 政策與 SendMessage 許可連接起來。這項政策可讓您將訊息從 API 發佈到 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 佇列名稱。

  1. 在 API Gateway 中建立 REST API
  2. API Gateway 主控台中,建立適用於 REST API 的 Amazon SQS 整合。
  3. 建立 REST API 資源或 REST API 方法
    資源畫面上,選擇建立方法
    針對方法類型,選擇 POST
    對於整合類型,請選擇 AWS 服務
    對於 AWS Region (AWS 區域),請選擇您的區域。
    對於 AWS Service (AWS 服務),請選擇 Simple Queue Service (SQS)
    對於 AWS Subdomain (AWS 子網域),請保留空白。這是一個選擇性參數,您可以在其中輸入 AWS 服務使用的子網域。請檢查 AWS 服務的文件以確認子網域的可用性。
    對於 HTTP method (HTTP 方法),請選擇 POST
    對於 Action Type (動作類型),選擇 Use path override (使用路徑覆寫)。
    對於 Path override (路徑覆寫),請輸入 / 字元。
    對於 Execution role (執行角色),請輸入 IAM 角色的 ARN。
    對於 Default Timeout (預設逾時),請選擇設定的選項。
    展開 HTTP request headers (HTTP 請求標頭)。
    選擇 Add header (新增標頭)。
    對於名稱,請輸入 Content-Type
    選擇 Add header (新增標頭)。
    對於 Name (名稱),請輸入 X-Amz-Target
    選取 Create method (建立方法)。
    選擇 POST 方法整合請求
    選擇編輯
    對於 Request body passthrough (請求內文傳遞),請保留預設選項 When no template matches the request content-type header (若沒有範本符合要求內容類型標頭)。
    展開 URL 請求標頭參數
    選擇新增請求標頭參數
    對於名稱,請輸入 Content-Type
    對於 Mapped from (映射自),請輸入 method.request.header.Content-Type
    選擇新增請求標頭參數
    對於 Name (名稱),請輸入 X-Amz-Target
    對於 Mapped from (映射自),請輸入 method.request.header.X-Amz-Target
    選擇 Save (儲存)。
  4. 部署 REST API
  5. 若要測試設定,請將下列請求傳送至 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"}

注意事項: AWS JSON 通訊協定的預期回應與 AWS 查詢通訊協定不同,即使對於相同的 API 呼叫也不同。請參閱 SQS API 參考,作為來自每個通訊協定的範例回應。

解決常見錯誤

UnknownOperationException 錯誤

您可能從 AWS 查詢通訊協定和 AWS JSON 通訊協定中,取得 UnknownOperationException 錯誤。

如果您使用 AWS 查詢通訊協定,則當您未將 Content-Type 設定為整合請求 HTTP 標頭中的 "application/x-www-form-urlencoded" 時,將會取得 UnknownOperationException。您未將 SendMessage 動作新增至整合請求映射範本時,也會取得此錯誤。若要解決此錯誤,請確定 Content-Type 是否已正確格式化,並在映射範本中包含 SendMessage 動作。

如果您使用 AWS JSON 通訊協定,則當您未傳送或未正確設定 Content-TypeX-Amz-Target 標頭時,會取得 UnknownOperationException 錯誤。若要解決此錯誤,請將 Content-Type 標頭設定為 "application/x-amz-json-1.0",並將 X-Amz-Target 標頭設定為 AmazonSQS.{SQS-Action},並在請求中包含兩個標頭。

AccessDenied 錯誤

您可能從 AWS 查詢通訊協定和 AWS JSON 通訊協定中,取得 AccessDenied 錯誤。

API 整合執行角色未設定將訊息傳送至 SQS 佇列的 sqs:SendMessage 許可時,即會取得 AccessDenied 錯誤。

當您使用 AWS 查詢通訊協定並在請求內容承載字串中,傳遞不受支援的特殊字元時,也會取得此錯誤。您必須對特殊字元進行編碼以避免此錯誤。在映射範本中新增 $util.urlEncode() 函數,以將請求內容從字串轉換為編碼格式。下列內容為映射範本的範例:

Action=SendMessage&MessageBody=$util.urlEncode($input.body)

下列範例包含傳送訊息至 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 錯誤

您可能從 AWS 查詢通訊協定和 AWS JSON 通訊協定中,取得 KMS.AccessDeniedException 錯誤。

API 整合執行角色無法透過 AWS Key Management Service (AWS KMS) 執行操作時,會取得 KMS.AccessDeniedException 錯誤。若要解決此錯誤,請設定許可以對連接至 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 取代為執行角色名稱。

SignatureDoesNotMatch 錯誤

使用 AWS 查詢通訊協定時,您可能會取得 SignatureDoesNotMatch 錯誤。

整合請求HTTP 方法設定為 GET 而非 POST 時,會取得 SignatureDoesNotMatch 錯誤。若要解決此錯誤,請將 HTTP 方法設定為 POST。

InvalidAddress 錯誤

使用 AWS JSON 通訊協定時,您可能會收到 InvalidAddress 錯誤。

當內容承載中的 SQS 佇列 URL 不正確時,會收到 InvalidAddress 錯誤。若要解決此錯誤,請檢查 API 呼叫目標的 SQS 佇列之佇列 URL。

SerializationException 錯誤

使用 AWS JSON 通訊協定時,您可能會收到 SerializationException 錯誤。

當內容承載為無效的 JSON 時,會收到 SerializationException 錯誤。例如,您的 JSON 可能有缺少或額外的逗號,或缺少或額外的大括號。若要解決此錯誤,請使用 JSON 格式化工具查找 JSON 中的語法錯誤。

**MissingRequiredParameterException 錯誤 **

使用 AWS JSON 通訊協定時,您可能會收到 MissingRequiredParameterException 錯誤。

當您沒有在內容承載中包含一個或多個必要參數時,會取得 MissingRequiredParameterException 錯誤。所需的參數取決於您的 API 呼叫。例如,當缺少 MessageBody 參數時,會從 SendMessage API 呼叫取得此錯誤。檢查 SQS API 參考以獲取必要的參數和語法。

相關資訊

將 Amazon API Gateway 與 Amazon SQS 整合,以處理非同步 REST API

如何使用 API Gateway 作為另一個 AWS 服務的代理?