跳至內容

如何將 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 查詢通訊協定AWS JSON 通訊協定

使用 AWS 查詢通訊協定將 API Gateway REST API 與 Amazon SQS 整合

請完成以下步驟:

  1. 建立 SQS 佇列

  2. 為 AWS 服務建立 AWS Identity and Access Management (IAM) 角色
    **注意:**在 Service or use case (服務或使用案例),選取 API Gateway

  3. 若要允許您從 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 佇列名稱。

  4. 在 API Gateway 中建立 REST API

  5. API Gateway 主控台 中,為您的 REST API 建立 Amazon SQS 整合。

  6. 建立 REST API 資源或 REST API 方法
    Resources (資源) 頁面上,選擇 Create method (建立方法)。
    Method type (方法類型),請選擇 POST
    Integration type (整合類型),請選擇 AWS Service (AWS 服務)。
    AWS Region (AWS 區域),請選擇您的區域。
    AWS Service (AWS 服務),請選擇 Simple Queue Service (SQS)
    (選用) 在 AWS Subdomain (AWS 子網域),請輸入 AWS 服務所使用的子網域。請檢查服務文件以確認子網域的可用性。在 Amazon SQS 範例設定中,請保持此欄位空白。
    HTTP method (HTTP 方法),請選擇 POST
    Action Type (動作類型),請選擇 Use path override (使用路徑覆寫)。
    Path override (optional) (路徑覆寫 (選用)),請依下列格式輸入您的帳戶 ID 與 SQS 佇列名稱:example-account-id/example-sqs-queue-name。例如: 1234567890/MySQSStandardQueue
    Execution role (執行角色),請輸入 IAM 角色的 ARN。
    Integration timeout (整合逾時),請為您的設定選擇一個選項。
    繼續輸入您的 REST API 整合資訊。
    選擇 Create method (建立方法)。
    選擇 POST 方法的 Integration Request (整合請求)。
    選擇 Edit (編輯)。
    Request body passthrough (請求本文傳遞),請選取符合您需求的選項。
    展開 URL request headers parameters (URL 請求標頭參數)。
    選擇 Add request header parameter (新增請求標頭參數)。
    Name (名稱),請輸入 Content-Type
    Mapped from (對應來源),請輸入 'application/x-www-form-urlencoded'
    展開 Mapping Templates (對應範本)。
    選擇 Add mapping template (新增對應範本)。
    Content-Type,請輸入 application/json
    在範本,請輸入 Action=SendMessage&MessageBody=$input.body,然後選擇 Save (儲存)。

  7. 部署 REST API

  8. 若要測試此設定,請將下列請求傳送至 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 整合

請完成以下步驟:

  1. 建立 SQS 佇列

  2. 為 AWS 服務建立 IAM 角色
    **注意:**在 Service or use case (服務或使用案例),選取 API Gateway

  3. 若要允許您從 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 佇列名稱。

  4. 在 API Gateway 中建立 REST API

  5. API Gateway 主控台 中,為您的 REST API 建立 Amazon SQS 整合。

  6. 建立 REST API 資源或 REST API 方法
    Resources (資源) 頁面上,選擇 Create method (建立方法)。
    Method type (方法類型),請選擇 POST
    Integration type (整合類型),請選擇 AWS Service (AWS 服務)。
    AWS Region (AWS 區域),請選擇您的區域。
    AWS Service (AWS 服務),請選擇 Simple Queue Service (SQS)
    對於 AWS Subdomain (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 (新增標頭)。
    Name (名稱),請輸入 Content-Type
    選擇 Add header (新增標頭)。
    Name (名稱),請輸入 X-Amz-Target
    選取 Create method (建立方法)。
    選擇 POST 方法的 Integration Request (整合請求)。
    選擇 Edit (編輯)。
    Request body passthrough (請求本文傳遞),請維持預設選項 When no template matches the request content-type header (當沒有範本符合請求 content-type 標頭時)。
    展開 URL request headers parameters (URL 請求標頭參數)。
    選擇 Add request header parameter (新增請求標頭參數)。
    Name (名稱),請輸入 Content-Type
    Mapped from (對應來源),請輸入 method.request.header.Content-Type
    選擇 Add request header parameter (新增請求標頭參數)。
    Name (名稱),請輸入 X-Amz-Target
    Mapped from (對應來源),請輸入 method.request.header.X-Amz-Target
    選擇 Save (儲存)。

  7. 部署 REST API

  8. 若要測試此設定,請將下列請求傳送至 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 Query 通訊協定不同,即使是相同的 API 呼叫也不同。

解決常見的 SQS 錯誤

若要解決常見 Amazon SQS 錯誤,請依照您收到的錯誤訊息執行下列疑難排解步驟。

「UnknownOperationException」錯誤

您可能會從 AWS Query 通訊協定與 AWS JSON 通訊協定收到「UnknownOperationException」錯誤。

若您使用 AWS Query 通訊協定,當您未在整合請求 HTTP 標頭中將 Content-Type 設定為 "application/x-www-form-urlencoded" 時,就會發生此錯誤。當您未在整合請求的對應範本中加入 SendMessage 動作時,也會發生此錯誤。若要解決此錯誤,請確定正確設定 Content-Type,並在對應範本中包含 SendMessage 動作。

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

「AccessDenied」錯誤

您可能會從 AWS Query 通訊協定與 AWS JSON 通訊協定收到**「AccessDenied」**錯誤。

當 API 整合執行角色未設定 sqs:SendMessage 權限以將訊息傳送至 SQS 佇列時,就會發生此錯誤。

當您使用 AWS Query 通訊協定並在請求本文承載字串中傳遞不支援的特殊字元時,也會發生此錯誤。您必須將特殊字元進行編碼以避免此錯誤。請在對應範本中新增 $util.urlEncode() 函式,將請求本文從字串轉換為已編碼格式。以下為對應範本範例:

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

若您使用 Amazon SQS 先進先出 (FIFO) 佇列,請務必包含 MessageGroupIdMessageDeduplicationId 屬性之一。以下為 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」錯誤

您可能會從 AWS Query 通訊協定與 AWS JSON 通訊協定收到「KMS.AccessDeniedException」錯誤。

當 API 整合執行角色無法透過 AWS Key Management Service (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」錯誤

您可能會從 AWS Query 通訊協定與 AWS JSON 通訊協定收到「MalformedQueryString」錯誤。

當請求本文承載字串中包含特殊字元時,就會發生此錯誤。請在對應範本中新增 $util.urlEncode() 函式,將請求本文從字串轉換為已編碼格式。以下為對應範本範例:

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

「SignatureDoesNotMatch」錯誤

當您使用 AWS Query 通訊協定時,可能會收到「SignatureDoesNotMatch」錯誤。

integration request (整合請求) 的 HTTP method (HTTP 方法) 設定為 GET 而非 POST 時,就會發生此錯誤。若要解決此錯誤,請將 HTTP method (HTTP 方法) 設定為 POST。

「InvalidAddress」錯誤

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

當本文承載中的 SQS 佇列網址不正確時,就會發生此錯誤。若要解決此錯誤,請檢查 API 呼叫所針對的 SQS 佇列之佇列網址。

「SerializationException」錯誤

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

當本文承載不是有效的 JSON 時,就會發生此錯誤。例如,您的 JSON 可能缺少或多出逗號,或缺少或多出大括號。若要解決此錯誤,請將您的 JSON 修正為有效格式。

「MissingRequiredParameterException」錯誤

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

當您的本文承載中未包含一個或多個必要參數時,就會發生此錯誤。必要參數取決於您的 API 呼叫。例如,當 MessageBody 參數遺漏時,您會從 SendMessage API 呼叫收到此錯誤。請參閱 SQS API Reference 以了解必要參數與語法。

相關資訊

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

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