Como faço para integrar uma API REST do API Gateway com o Amazon SQS e resolver erros comuns?

6 minuto de leitura
0

Quero integrar uma API REST do Amazon API Gateway com o Amazon Simple Queue Service (Amazon SQS). Também quero solucionar erros de integração.

Resolução

Você pode configurar as APIs REST do API Gateway para trabalhar com o Amazon SQS para criar uma solução integrada.

Configurar a API REST e uma integração com o Amazon SQS

Para integrar uma API REST da API Gateway com o Amazon SQS, siga estas etapas:

1.    Crie uma fila SQS.

2.    Crie um perfil do AWS Identity and Access Management (IAM) e, em seguida, anexe uma política do Amazon SQS com uma permissão SendMessage. Essa política permite que mensagens da API sejam publicadas no Amazon SQS. Na política, substitua example-region pela sua região da AWS, example-account-id pelo ID da conta da AWS e example-sqs-queue-name pelo nome da fila do 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.    Crie uma API REST no API Gateway.

4.    No console do API Gateway, crie uma integração do Amazon SQS para sua API REST recém-criada.

  • Opcionalmente, crie um recurso da API REST ou um método da API REST.
  • Crie um método POST.
    Em Integration type (Tipo de integração), selecione AWS Service (Serviço da AWS).
    Em AWS Region (Região da AWS), selecione sua região da AWS.
    Em AWS Service (Serviço da AWS), escolha Simple Queue Service (SQS).
    (Opcional) Para o AWS Subdomain (Subdomínio da AWS), insira o subdomínio que o serviço da AWS usa. Verifique a documentação do serviço da AWS para confirmar a disponibilidade de um subdomínio. Para o exemplo de configuração do Amazon SQS, deixe isso em branco.
    Em HTTP method (Método HTTP), selecione POST.
    Em Action Type (Tipo de ação), escolha Use path override (Usar substituição de caminho).
    Em Path override (optional) (Substituição de caminho [opcional]), insira o ID da conta e o nome da fila SQS no seguinte formato: example-account-id/example-sqs-queue-name. Por exemplo, 1234567890/MySQSStandardQueue.
    Em Execution role (Função de execução), insira o ARN do perfil do IAM criado na etapa 2.
    Em Content Handling (Tratamento de conteúdo), escolha a opção que se adapta à sua configuração.
    Desmarque ou selecione Default Timeout (Tempo limite padrão). Escolha a opção que se adapta à sua configuração.
    Salve o novo método POST.
  • Continue inserindo suas informações de integração da API REST.
    Escolha a Integration Request (Solicitação de integração) do método POST.
    Expanda os HTTP Headers (Cabeçalhos HTTP).
    Escolha Add header (Adicionar cabeçalho).
    Em Name (Nome), insira Content-Type.
    Em Mapped from (Mapeado de), insira 'application/x-www-form-urlencoded' e escolha Create (Criar).
    Expanda Mapping Templates (Modelos de mapeamento).
    Em Request body passthrough (Passthrough do corpo da solicitação), selecione a opção que atenda às suas necessidades.
    Escolha Add mapping template (Adicionar modelo de mapeamento).
    Em Content-Type, insira application/json e escolha Create (Criar).
    Para o modelo, insira Action=SendMessage&MessageBody=$input.body

4.    Implemente a API REST configurada.

5.    Teste a configuração enviando a seguinte solicitação para o API Gateway. Substitua example-api-id pelo ID da API, example-region pela sua região da AWS, example-stage pelo nome do estágio de teste e example-resource pelo nome do recurso.

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

Quando sua integração for bem-sucedida, sua resposta será semelhante à seguinte:

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

Resolvendo erros comuns

Erro UnknownOperationException

Um erro UnknownOperationException ocorre quando um usuário não configura o Content-Type como "application/x-www-form-urlencoded" no cabeçalho HTTP da solicitação de integração. O erro UnknownOperationException também ocorre quando a SendMessage action (ação SendMessage) não é adicionada ao modelo de mapeamento da solicitação de integração.

AccessDenied error (Erro AccessDenied)

Veja a seguir um exemplo de erro 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"
}

Um erro AccessDenied ocorre quando a função de execução da integração da API não tem a permissão sqs:SendMessage definida para enviar mensagens para a fila do SQS. O erro AccessDenied também pode ocorrer quando caracteres especiais como “&” e “%” são passados na carga útil do corpo da solicitação. Você deve codificar os caracteres especiais para passar. Adicione a função $util.urlEncode() no modelo de mapeamento para converter o corpo da solicitação de uma string em um formato codificado. Veja a seguir um exemplo de modelo de mapeamento:

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

O exemplo a seguir inclui as permissões necessárias para enviar mensagens para a fila do SQS. Substitua example-region pela sua região da AWS, example-account-id pelo ID da sua conta da AWS e example-sqs-queue-name pelo nome da fila do SQS.

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

Erro KMS.AccessDeniedException

A seguir estão dois exemplos de erros de 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"
}

Um erro KMS.AccessDeniedException ocorre quando a função de execução da integração da API não consegue realizar operações por meio do AWS Key Management Service (AWS KMS). As permissões devem ser configuradas para realizar operações nas chaves do AWS KMS que estão anexadas à fila criptografada do lado do servidor do Amazon SQS.

O exemplo a seguir inclui as permissões necessárias para realizar operações nas chaves do KMS anexadas à fila do SQS. Substitua example-account-id pelo ID da sua conta da AWS e example-api-gw-integration-execution-role pelo nome da sua função de execução.

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