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

3 分的閱讀內容
0

我想將 Amazon API Gateway REST API 與 Amazon Simple Queue Service (Amazon SQS) 整合在一起。我也想解決整合錯誤。

解決方案

您可以設定 API Gateway REST API,以便使用 Amazon SQS 建立整合式解決方案。

設定 REST API 和 Amazon SQS 整合

若要整合 API Gateway REST API 與 Amazon SQS,請依照下列步驟執行:

1.    建立 SQS 佇列

2.    建立 AWS Identity and Access Management (IAM) 角色,然後附加具有 SendMessage (傳送訊息) 許可的 Amazon SQS 政策。此政策可讓您將來自 API 的訊息發佈到 Amazon SQS。在政策中,將 example-region (範例–區域) 取代為您的 AWS 區域、將 example-account-id (範例–帳戶–ID) 取代為您的 AWS 帳戶 ID,以及將 example-sqs-queue-name (範例–SQS–佇列–名稱) 取代為您的 SQS 佇列名稱。

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Resource": [
        "arn:aws:sqs:example-region:example-account-id:example-sqs-queue-name"
      ],
      "Action": [
        "sqs:SendMessage"
      ]
    }
  ]
}

3.    在 API Gateway 中建立 REST API

4.    在 API Gateway 主控台中,為新建立的 REST API 建立 Amazon SQS 整合。

  • 選擇性地建立 REST API 資源REST API 方法
  • 建立 POST 方法
    Integration type (整合類型),請選擇 AWS Service (AWS 服務)。
    AWS 區域,請選擇您的 AWS 區域。
    AWS 服務,請選擇 Simple Queue Service (SQS)
    (選用) 針對 AWS Subdomain (AWS 子網域),請輸入 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 (執行角色),請輸入在 step 2 (步驟 2) 中建立的 IAM 角色的 ARN。
    針對 Content Handling (內容處理),請選擇適合您設定的選項。
    清除或選取 預設逾時。選擇適合您設定的選項。
    儲存新的 POST 方法。
  • 繼續輸入您的 REST API 整合資訊。
    選擇 POST 方法 Integration Request (整合請求)。
    展開 HTTP Headers (HTTP 標題)。
    選擇 Add header (新增標題)。
    針對 Name (名稱),請輸入 Content-Type (內容–類型)。
    針對 Mapped from (映射來源),請輸入 'application/x-www-form-urlencoded',然後選擇 Create (建立)。
    展開 Mapping Templates (映射範本)。
    Request body passthrough (請求主體直通),請選取符合您需求的選項。
    選擇 Add mapping template (新增映射範本)。
    針對 Content-Type (內容–類型) 中,請輸入 application/json,然後選擇 Create (建立)。
    針對範本,請輸入 Action=SendMessage&MessageBody=$input.body

4.    部署已設定的 REST API

5.    將下列請求傳送至 API Gateway 來測試設定。用您的 API ID 取代 example-api-id (範例–API–ID),用您的 AWS 區域取代 example-region (範例–區域),用您的測試階段名稱取代 example-stage (範例–階段),以及用您的資源名稱取代 example-resource (範例–資源)。

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"
  }'

整合成功時,您的回應類似於下列內容:

{
  "SendMessageResponse": {
    "ResponseMetadata": {
      "RequestId": "f879fb11-e736-52c0-bd29-a0f2d09ad90d"
    },
      "SendMessageResult": {
        "MD5OfMessageAttributes": null,
        "MD5OfMessageBody": "3fc759ac1733366f98ec4270c788fcd1",
        "MD5OfMessageSystemAttributes": null,
        "MessageId": "4c360c3c-08f4-4392-bc14-8b0c88e314a2",
        "SequenceNumber": null
    }
  }
}

解決常見錯誤

UnknownOperationException 錯誤

使用者無法在整合請求 HTTP 標題中將 Content-Type (內容–類型) 設定為 "application/x-www-form-urlencoded" 時,就會發生 UnknownOperationException 錯誤。SendMessage 動作未新增至整合請求映射範本時,也會發生 UnknownOperationException 錯誤。

AccessDenied 錯誤

以下是 AccessDenied 錯誤的範例:

{
  "Error": {
    "Code": "AccessDenied",
    "Message": "Access to the resource https://sqs.example-region.amazonaws.com/example-account-id/example-sqs-queue-name is denied.",
    "Type": "Sender"
  },
  "RequestId": "92aea8b7-47f1-5bd4-b3c4-f3d0688d3809"
}

API 整合執行角色沒有將訊息傳送至 SQS 佇列的 sqs:SendMessage 許可設定時,就會發生 AccessDenied 錯誤。在請求主體承載中傳遞特殊字元 (例如 "&" 和 "%") 時,也會發生 AccessDenied 錯誤。必須對要傳遞的特殊字元進行編碼。在映射範本中新增 $util.urlEncode() 函數,以將請求主體從字元串轉換為編碼格式。以下是映射範本的範例:

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

下列範例包含將訊息傳送至 SQS 佇列所需的許可。用您的 AWS 區域取代 example-region (範例–區域) 取代為,用您的 AWS 帳戶 ID 取代 example-account-id (範例–帳戶–ID),以及用您的 SQS 佇列名稱取代 example-sqs-queue-name (範例–SQS–佇列–名稱)。

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Resource": [
        "arn:aws:sqs:example-region:example-account-id:example-sqs-queue-name"
      ],
      "Action": [
        "sqs:SendMessage"
      ]
    }
  ]
}

KMS.AccessDeniedException 錯誤

以下是 KMS.AccessDeniedException 錯誤的兩個範例:

{
  "Error": {
    "Code": "KMS.AccessDeniedException",
    "Message": "User: arn:aws:sts::example-account-number:assumed-role/example-sqs-queue-name/BackplaneAssumeRoleSession is not authorized to perform: kms:GenerateDataKey on resource: arn:aws:kms:example-region:example-account-number:key/example-keyId because no identity-based policy allows the kms:GenerateDataKey action (Service: AWSKMS; Status Code: 400; Error Code: AccessDeniedException; Request ID: c58f1eec-6b18-4029-826b-d05d6a715716; Proxy: null)",
    "Type": "Sender"
  },
  "RequestId": "99976a6a-3311-57e9-86e9-310d0654ff80"
}
{
  "Error": {
    "Code": "KMS.AccessDeniedException",
    "Message": "The ciphertext refers to a customer master key that does not exist, does not exist in this region, or you are not allowed to access. (Service: AWSKMS; Status Code: 400; Error Code: AccessDeniedException; Request ID: a8adea02-c246-49d9-8b3d-ff6b6a43b40f; Proxy: null)",
    "Type": "Sender"
  },
  "RequestId": "9565c451-742c-55f3-a1eb-9f3641fd30aa"
}

API 整合執行角色無法透過 AWS Key Management Service (KMS) 執行操作時,就會發生 KMS.AccessDeniedException 錯誤。必須設定許可,才能對連接到 Amazon SQS 伺服器端加密佇列的 AWS KMS key 執行操作。

下列範例包含對連接到 SQS 佇列的 KMS 金鑰執行作業所需的許可。用您的 AWS 帳戶 ID取代 example-account-id (範例–帳戶–ID),並用您的執行角色名稱取代 example-api-gw-integration-execution-role (範例–API–GW–整合–執行–角色)。

{
  "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": "*"
}

AWS 官方
AWS 官方已更新 1 年前