Saltar al contenido

¿Cómo integro una API de REST de API Gateway con Amazon SQS y soluciono los errores comunes?

10 minutos de lectura
0

Quiero integrar una API de REST de Amazon API Gateway con Amazon Simple Queue Service (Amazon SQS) y solucionar los errores de integración.

Resolución

Para integrar una API de REST de API Gateway con Amazon SQS, utiliza el protocolo de consultas de AWS o el protocolo JSON de AWS.

Uso del protocolo de consultas de AWS para integrar una API de REST de API Gateway con Amazon SQS

Sigue estos pasos:

  1. Crea una cola de SQS.

  2. Crea un rol de AWS Identity and Access Management (IAM) para un servicio de Amazon.
    Nota: En Servicio o caso de uso, elige API Gateway.

  3. Para permitirle publicar mensajes desde la API en Amazon SQS, adjunta la siguiente política de Amazon SQS con permisos de SendMessage:

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

    Nota: Sustituya example-region por tu región de AWS, example-account-id por tu ID de cuenta de AWS y example-sqs-queue-name por el nombre de tu cola de SQS.

  4. Crea una API de REST en API Gateway.

  5. En la consola de API Gateway, crea una integración de Amazon SQS para tu API de REST.

  6. Crea un recurso de API de REST o un método de API de REST:
    En la página Recursos, selecciona Crear método.
    En Tipo de método, elige POST.
    En Tipo de integración, elige Servicio de AWS.
    En Región de AWS, elige tu región.
    En Servicio de AWS, elige Simple Queue Service (SQS).
    (Opcional) En Subdominio de AWS, introduce el subdominio que utiliza el servicio de AWS. Consulta la documentación del servicio para confirmar la disponibilidad de un subdominio. Para la configuración de ejemplo de Amazon SQS, deja este campo en blanco.
    En Método HTTP, elige POST.
    En Tipo de acción, elige Usar sustitución de ruta.
    En Sustituir ruta (opcional), introduce el ID de tu cuenta y el nombre de cola de SQS en el siguiente formato: example-account-id/example-sqs-queue-name. Por ejemplo: 1234567890/MySQSStandardQueue.
    En Rol de ejecución, introduce el ARN del rol de IAM.
    En Tiempo de espera de la integración, elige una opción para tu configuración.
    Continúa introduciendo la información de integración de la API de REST.
    Selecciona Crear método.
    Elige Solicitud de integración del método POST.
    Selecciona Editar.
    En Transferencia del cuerpo de la solicitud, selecciona la opción que mejor se ajuste a tus necesidades.
    Amplía los parámetros de los encabezados de las solicitudes de URL.
    Elige Agregar parámetro del encabezado de solicitud.
    En Nombre, introduce Content-Type.
    En Asignado desde, escribe «application/x-www-form-urlencoded».
    Expande Plantillas de asignación.
    Selecciona Agregar plantilla de asignación.
    En Content-Type, introduce application/json.
    Para la plantilla, escribe Action=SendMessage&MessageBody=$input.body y, a continuación, selecciona Guardar.

  7. Despliega la API de REST.

  8. Para probar la configuración, envía la siguiente solicitud a 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"  
      }'
    

    Nota: Sustituye example-api-id por tu ID de API, example-region por tu región, example-stage por el nombre de tu etapa de prueba y example-resource por el nombre de tu recurso.
    Ejemplo de respuesta de integración exitosa:

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

Uso del protocolo JSON de AWS para integrar una API de REST de API Gateway con Amazon SQS

Sigue estos pasos:

  1. Crea una cola de SQS.

  2. Crea un rol de IAM para un servicio de AWS.
    Nota: En Servicio o caso de uso, elige API Gateway.

  3. Para permitirle publicar mensajes desde la API en Amazon SQS, adjunta la siguiente política de Amazon SQS con permisos de SendMessage:

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

    Nota: Sustituya example-region por tu región de AWS, example-account-id por tu ID de cuenta de AWS y example-sqs-queue-name por el nombre de tu cola de SQS.

  4. Crea una API de REST en API Gateway.

  5. En la consola de API Gateway, crea una integración de Amazon SQS para tu API de REST.

  6. Crea un recurso de API de REST o un método de API de REST:
    En la página Recursos, selecciona Crear método.
    En Tipo de método, elige POST.
    En Tipo de integración, elige Servicio de AWS.
    En Región de AWS, elige tu región.
    En Servicio de AWS, elige Simple Queue Service (SQS).
    En Subdominio de AWS, deja el campo en blanco. Se trata de un parámetro opcional en el que se introduce el subdominio que utiliza un servicio de AWS. Consulta la documentación del servicio para confirmar la disponibilidad de un subdominio.
    En Método HTTP, elige POST.
    En Tipo de acción, elige Usar sustitución de ruta.
    En Sustitución de ruta, introduce el carácter /.
    En Rol de ejecución, introduce el ARN del rol de IAM.
    En Tiempo de espera predeterminado, elige una opción para tu configuración.
    Amplía los encabezados de las solicitudes HTTP.
    Selecciona Agregar encabezado.
    En Nombre, introduce Content-Type.
    Selecciona Agregar encabezado.
    En Nombre, escribe X-Amz-Target.
    Selecciona Crear método.
    Elige Solicitud de integración del método POST.
    Selecciona Editar.
    En Transferencia del cuerpo de la solicitud, establece la opción Cuando ninguna plantilla coincida con el encabezado del tipo de contenido de la solicitud como predeterminada.
    Amplía los parámetros de los encabezados de las solicitudes de URL.
    Elige Agregar parámetro del encabezado de solicitud.
    En Nombre, introduce Content-Type.
    En Asignado desde, introduce method.request.header.Content-Type.
    Elige Agregar parámetro del encabezado de solicitud.
    En Nombre, escribe X-Amz-Target.
    En Asignado desde, introduce method.request.header.X-Amz-Target.
    Selecciona Guardar.

  7. Despliega la API de REST.

  8. Para probar la configuración, envía la siguiente solicitud a 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"
    }'

    Nota: Sustituye example-api-id por tu ID de API, example-region por tu región, example-stage por el nombre de tu etapa de prueba y example-resource por el nombre de tu recurso. Para buscar el valor QueueUrl, consulta los detalles de cola de Amazon SQS.

Ejemplo de respuesta de integración exitosa:

{"MD5OfMessageBody":"fafb00f5732ab283681e124bf8747ed1","MessageId":"b5aef1f3-af31-49f2-9973-6f802f7753e6"}

Nota: La respuesta esperada del protocolo JSON de AWS es diferente a la del protocolo de consulta de AWS, incluso en la misma llamada a la API.

Resolución de errores comunes de SQS

Para resolver los errores comunes de Amazon SQS, sigue estos pasos de solución de problemas para el mensaje de error que has recibido.

Error "UnknownOperationException"

Puedes recibir un error "UnknownOperationException" tanto en el protocolo de consulta de AWS como en el protocolo JSON de AWS.

Si usas el protocolo de consulta de AWS, este error se produce cuando no configuras el encabezado Content-Type como «application/x-www-form-urlencoded» en el encabezado HTTP de la solicitud de integración. Este error también se produce cuando no se agrega la acción SendMessage a la plantilla de asignación de la solicitud de integración. Para resolver este error, asegúrate de que Content-Type tenga el formato correcto e incluye la acción SendMessage en la plantilla de asignación.

Si usas el protocolo JSON de AWS, recibirás este error si no envías o no configuras correctamente los encabezados Content-Type y X-Amz-Target. Para resolver este error, configura el encabezado Content-Type como «application/x-amz-json-1.0», configura el encabezado X-Amz-Target como AmazonSQS.{SQS-Action} e incluye ambos encabezados en la solicitud.

Error "AccessDenied"

Puedes recibir un error "AccessDenied" tanto en el protocolo de consulta de AWS como en el protocolo JSON de AWS.

Este error se produce cuando el rol de ejecución de la integración de la API no tiene el permiso sqs:SendMessage establecido para enviar mensajes a la cola de SQS.

Este error también aparece cuando utilizas el protocolo de consulta de AWS y agregas caracteres especiales no admitidos en la cadena de carga útil del cuerpo de la solicitud. Debes codificar los caracteres especiales para evitar este error. Agrega la función $util.urlEncode() en la plantilla de asignación para convertir el cuerpo de la solicitud de una cadena a un formato codificado. A continuación se muestra un ejemplo de plantilla de asignación:

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

Si utilizas una cola FIFO (First-In-First-Out) de Amazon SQS, asegúrate de incluir el atributo MessageGroupId o MessageDeduplicationId. A continuación, se muestra un ejemplo de plantilla de asignación FIFO:

Action=SendMessage&MessageBody=$util.urlEncode($input.body)&MessageGroupId=$your-msg-group-id&MessageDeduplicationId=$your-msg-dedup-id

Nota: Sustituye your-msg-group-id por tu ID de grupo de mensajes y your-msg-dedup-id por tu ID de deduplicación de mensajes.

El siguiente ejemplo incluye los permisos necesarios para enviar mensajes a la cola de SQS:

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

Nota: Sustituye example-region por tu región, example-account-id por tu ID de cuenta y example-sqs-queue-name por tu nombre de cola de SQS.

Error "KMS.AccessDeniedException"

Puedes recibir un error "KMS.AccessDeniedException" tanto del protocolo de consulta de AWS como del protocolo JSON de AWS.

Este error se produce cuando el rol de ejecución de la integración de la API no puede realizar operaciones a través de AWS Key Management Service (AWS KMS). Para resolver este error, debes configurar los permisos para realizar operaciones en las claves de AWS KMS que están adjuntas a la cola cifrada del lado del servidor de Amazon SQS.

El siguiente ejemplo incluye los permisos necesarios para realizar operaciones en las claves de KMS que están asociadas a la cola de SQS:

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

Nota: Sustituye example-account-id por el ID de tu cuenta y example-api-gw-integration-execution-role por el nombre de tu rol de ejecución.

Error "MalformedQueryString"

Puedes recibir el error "MalformedQueryString" tanto en el protocolo de consulta de AWS como en el protocolo JSON de AWS.

Este error se produce cuando hay caracteres especiales en la cadena de carga útil del cuerpo de la solicitud. Agrega la función $util.urlEncode() en la plantilla de asignación para convertir el cuerpo de la solicitud de una cadena a un formato codificado. A continuación se muestra un ejemplo de plantilla de asignación:

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

Error "SignatureDoesNotMatch"

Puedes recibir un error "SignatureDoesNotMatch" cuando usas el protocolo de consulta de AWS.

Este error se produce cuando el método HTTP de la solicitud de integración se establece en GET en lugar de POST. Para resolver este error, establece el método HTTP en POST.

Error "InvalidAddress"

Puedes recibir un error "InvalidAddress" cuando usas el protocolo JSON de AWS.

Este error se produce cuando la URL de la cola de SQS en la carga útil del cuerpo es incorrecta. Para resolver este error, comprueba la URL de la cola de SQS a la que se dirige la llamada a la API.

Error "SerializationException"

Puedes recibir un error "SerializationException" cuando usas el protocolo JSON de AWS.

Este error se produce cuando la carga útil del cuerpo no es un JSON válido. Por ejemplo, es posible que al formato JSON le falte una coma o un corchete o que tenga una coma o corchete de más. Para resolver este error, cambia tu JSON a un formato válido.

Error "MissingRequiredParameterException"

Puedes recibir un error "MissingRequiredParameterException" cuando usas el protocolo JSON de AWS.

Este error se produce cuando no incluyes uno o más de los parámetros obligatorios en la carga útil del cuerpo. Los parámetros necesarios dependen de la llamada a la API. Por ejemplo, verás este error en una llamada a la API SendMessage cuando falta el parámetro MessageBody. Consulta la referencia de la API de SQS para ver los parámetros y la sintaxis necesarios.

Información relacionada

Integración de Amazon API Gateway con Amazon SQS para gestionar las API de REST asincrónicas

¿Cómo utilizo API Gateway como proxy para otro servicio de AWS?