

# Desarrollo de las API de WebSocket en API Gateway
<a name="websocket-api-develop"></a>

En esta sección se proporciona información detallada acerca de las capacidades de API Gateway que necesitará para desarrollar las API de API Gateway.

A medida que se desarrolla la API de API Gateway, se decide sobre una serie de características de la API. Estas características dependen del uso de la API. Por ejemplo, es posible que quiera permitir solo a ciertos clientes llamar a la API o puede que quiera que esté disponible para todos. Quizás desee que una llamada a la API ejecute una función de Lambda, haga una consulta a la base de datos o llame a una aplicación.

**Topics**
+ [Creación de las API de WebSocket en API Gateway](apigateway-websocket-api-create-empty-api.md)
+ [Tipos de direcciones IP para las API de WebSocket en API Gateway](websocket-api-ip-address-type.md)
+ [Creación de rutas para las API de WebSocket en API Gateway](websocket-api-develop-routes.md)
+ [Control y administración del acceso a las API de WebSocket en API Gateway](apigateway-websocket-api-control-access.md)
+ [Integraciones de API de WebSocket en API Gateway](apigateway-websocket-api-integrations.md)
+ [Solicitud de la validación de las API de WebSocket en API Gateway](websocket-api-request-validation.md)
+ [Transformaciones de datos para las API de WebSocket en API Gateway](websocket-api-data-transformations.md)
+ [Tipos de medios binarios para las API de WebSocket en API Gateway](websocket-api-develop-binary-media-types.md)
+ [Invocación de las API de WebSocket](apigateway-how-to-call-websocket-api.md)

# Creación de las API de WebSocket en API Gateway
<a name="apigateway-websocket-api-create-empty-api"></a>

Puede crear una API de WebSocket en la consola de API Gateway mediante el comando [create-api](https://docs.aws.amazon.com/cli/latest/reference/apigatewayv2/create-api.html) de la AWS CLI o mediante el comando `CreateApi` en un AWS SDK. Los procedimientos que se describen a continuación muestran cómo crear una API de WebSocket nueva.

**nota**  
Las API de WebSocket solo son compatibles con TLS 1.2 y TLS 1.3. No se admiten versiones de TLS anteriores.

## Creación de una API de WebSocket mediante comandos de la AWS CLI
<a name="apigateway-websocket-api-create-using-awscli"></a>

El siguiente comando [create-api](https://docs.aws.amazon.com/cli/latest/reference/apigatewayv2/create-api.html) permite crear una API con la expresión de selección de ruta `$request.body.action`:

```
aws apigatewayv2 --region us-east-1 create-api --name "myWebSocketApi3" --protocol-type WEBSOCKET --route-selection-expression '$request.body.action'
```

El resultado es similar al siguiente:

```
{
    "ApiKeySelectionExpression": "$request.header.x-api-key",
    "Name": "myWebSocketApi3",
    "CreatedDate": "2018-11-15T06:23:51Z",
    "ProtocolType": "WEBSOCKET",
    "RouteSelectionExpression": "'$request.body.action'",
    "ApiId": "aabbccddee"
}
```

## Creación de una API de WebSocket mediante la consola de API Gateway
<a name="apigateway-websocket-api-create-using-console"></a>

Para crear una API de WebSocket en la consola, elija el protocolo WebSocket y asígnele un nombre a la API.

**importante**  
Una vez que haya creado la API, no podrá cambiar el protocolo que haya elegido para ella. No hay forma de convertir una API de WebSocket en una API de REST o viceversa.

**Para crear una API de WebSocket mediante la consola de API Gateway**

1. Inicie sesión en la consola de API Gateway y elija **Create API (Crear API)**.

1. En **WebSocket API (API de WebSocket)**, elija **Build (Generar)**. Solo se admiten puntos de conexión regionales.

1. En **Nombre de API**, escriba el nombre de la API.

1. En **Expresión de selección de ruta**, introduzca un valor. Por ejemplo, `$request.body.action`. 

   Para obtener más información sobre las expresiones de selección de ruta, consulte [Expresiones de selección de ruta](websocket-api-develop-routes.md#apigateway-websocket-api-route-selection-expressions).

1. Realice una de las siguientes acciones:
   + Elija **Crear una API en blanco** para crear una API sin rutas.
   + Seleccione **Siguiente** para asociar rutas a su API.

   Puede asociar rutas después de crear su API.

# Tipos de direcciones IP para las API de WebSocket en API Gateway
<a name="websocket-api-ip-address-type"></a>

Al crear una API, se especifica el tipo de direcciones IP que puede invocar la API. Puede elegir IPv4 para resolver las direcciones IPv4 para invocar la API o puede elegir pila doble para permitir que las direcciones IPv4 e IPv6 invoquen la API. Le recomendamos que establezca el tipo de dirección IP en pila doble para mitigar el agotamiento del espacio IP o para mejorar la postura de seguridad. Para obtener más información sobre los beneficios de un tipo de dirección IP de pila doble, consulte [IPv6 en AWS](https://docs.aws.amazon.com/whitepapers/latest/ipv6-on-aws/internet-protocol-version-6.html).

## Consideraciones para los tipos de direcciones IP
<a name="websocket-api-ip-address-type-considerations"></a>

Es posible que las siguientes consideraciones afecten al uso de los tipos de direcciones IP:
+ El tipo de dirección IP predeterminado para todas las API de WebSocket es IPv4.
+ Si cambia el tipo de dirección IP de una API existente de IPv4 a pila doble, confirme que todas las políticas que controlan el acceso a las API se hayan actualizado para tener en cuenta las llamadas de IPv6. Cuando cambia el tipo de dirección IP, el cambio surte efecto inmediatamente.
+ La API se puede asignar a un nombre de dominio personalizado con un tipo de dirección IP diferente al de la API. Si desactiva el punto de conexión de la API predeterminado, esto podría afectar a la forma en que los intermediarios pueden invocar a la API.

## Cambio del tipo de dirección IP de una API de WebSocket
<a name="websocket-api-ip-address-type-change"></a>

Puede cambiar el tipo de dirección IP actualizando la configuración de la API. Puede actualizar la configuración de la API mediante el uso de la Consola de administración de AWS, la AWS CLI, CloudFormation o un AWS SDK. Si cambia el tipo de dirección IP de la API, no es necesario volver a implementar la API para que los cambios surtan efecto. 

------
#### [ Consola de administración de AWS ]

**Cambio del tipo de dirección IP de una API de WebSocket**

1. Inicie sesión en la consola de API Gateway, en [https://console.aws.amazon.com/apigateway](https://console.aws.amazon.com/apigateway).

1. Elija una API de WebSocket.

1. Elija **Configuración de la API** y, a continuación, elija **Editar**.

1. Para tipo de dirección IP, seleccione **IPv4** o **Pila doble**.

1. Seleccione **Save**.

   El cambio en la configuración de la API se aplicará de forma inmediata.

------
#### [ AWS CLI ]

El siguiente comando [update-api](https://docs.aws.amazon.com/cli/latest/reference/apigatewayv2/update-api.html) actualiza una API para que tenga un tipo de dirección IP de pila doble:

```
aws apigatewayv2 update-api \
    --api-id abcd1234 \
    --ip-address-type dualstack
```

El resultado será similar al siguiente:

```
{
    "ApiEndpoint": "https://abcd1234.execute-api.us-east-1.amazonaws.com",
    "ApiId": "abcd1234",
    "ApiKeySelectionExpression": "$request.header.x-api-key",
    "CreatedDate": "2025-02-04T22:20:20+00:00",
    "DisableExecuteApiEndpoint": false,
    "Name": "My-WebSocket-API",
    "ProtocolType": "WEBSOCKET",
    "RouteSelectionExpression": "$request.method $request.path",
    "Tags": {},
    "NotificationUris": [],
    "IpAddressType": "dualstack"
}
```

------

# Creación de rutas para las API de WebSocket en API Gateway
<a name="websocket-api-develop-routes"></a>

En la API de WebSocket, los mensajes JSON entrantes se dirigen a las integraciones de backend en función de las rutas que se hayan configurado. (Los mensajes que no son de JSON se dirigen a la ruta `$default` que se configure).

Una *ruta* incluye una *clave de ruta*, que es el valor que se espera una vez que se evalúa una *expresión de selección de ruta*. `routeSelectionExpression` es un atributo definido en el nivel de API. Especifica una propiedad JSON cuya presencia se espera en la carga del mensaje. Para obtener más información sobre las expresiones de selección de ruta, consulte [Expresiones de selección de ruta](#apigateway-websocket-api-route-selection-expressions).

Por ejemplo, si los mensajes JSON contienen una propiedad `action` y desea realizar diferentes acciones en función de esta propiedad, la expresión de selección de ruta podría ser `${request.body.action}`. La tabla de enrutamiento especificaría la acción que se debe realizar comparando el valor de la propiedad `action` con los valores de clave de ruta personalizados que se han definido en la tabla.

Existen tres rutas predefinidas que se pueden utilizar: `$connect`, `$disconnect` y `$default`. Además, es posible crear rutas personalizadas.
+ API Gateway llama a la ruta `$connect` al iniciarse una conexión persistente entre el cliente y una API de WebSocket.
+ API Gateway llama a la ruta `$disconnect` cuando el cliente o el servidor se desconecta de la API.
+ API Gateway llama a una ruta personalizada después de evaluar la expresión de selección de ruta con respecto al mensaje si se encuentra una ruta coincidente; esta coincidencia determina qué integración se invoca.
+ API Gateway llama a la ruta `$default` si la expresión de selección de ruta no puede evaluarse con respecto al mensaje o no se encuentra ninguna ruta coincidente.

## Expresiones de selección de ruta
<a name="apigateway-websocket-api-route-selection-expressions"></a>

Una *expresión de selección de ruta* se evalúa cuando el servicio está seleccionando la ruta que debe seguir un mensaje entrante. El servicio utiliza la ruta cuya `routeKey` coincida exactamente con el valor evaluado. Si no hay ninguna coincidencia y existe una ruta con la clave de ruta `$default`, se selecciona esta. Si no hay rutas que coincidan con el valor evaluado y no existe ninguna ruta `$default`, el servicio devuelve un error. En las API basadas en WebSocket, la expresión debe tener el formato `$request.body.{path_to_body_element}`.

Por ejemplo, supongamos que está enviando el siguiente mensaje JSON:

```
{
    "service" : "chat",
    "action" : "join",
    "data" : {
        "room" : "room1234"
   }
}
```

Es posible que desee seleccionar el comportamiento de la API en función de la propiedad `action`. En ese caso, podría definir la siguiente expresión de selección de ruta:

```
$request.body.action
```

En este ejemplo, `request.body` hace referencia a la carga JSON del mensaje y `.action` es una expresión [JSONPath](https://goessner.net/articles/JsonPath/). Puede utilizar cualquier expresión de ruta JSON después de `request.body`, pero tenga en cuenta que el resultado se representará en forma de cadena. Por ejemplo, si la expresión JSONPath devuelve una matriz de dos elementos, esta se presentará como la cadena `"[item1, item2]"`. Por este motivo, es conveniente que la expresión dé como resultado un valor y no una matriz ni un objeto.

Puede utilizar simplemente un valor estático o puede utilizar varias variables. En la tabla siguiente, se muestran ejemplos y sus resultados evaluados frente a la carga anterior.


| Expresión | Resultado evaluado | Descripción | 
| --- | --- | --- | 
| \$1request.body.action | join | Una variable desencapsulada | 
| \$1\$1request.body.action\$1 | join | Una variable encapsulada | 
| \$1\$1request.body.service\$1/\$1\$1request.body.action\$1 | chat/join | Varias variables con valores estáticos | 
| \$1\$1request.body.action\$1-\$1\$1request.body.invalidPath\$1  | join- | Si no se encuentra JSONPath, la variable se resueve como "". | 
| action | action | Valor estático | 
| \$1\$1default | \$1default | Valor estático | 

El resultado evaluado se utiliza para encontrar una ruta. Si hay una ruta con una clave de ruta coincidente, se selecciona la ruta para procesar el mensaje. Si no se encuentra ninguna ruta coincidente, API Gateway intenta encontrar la ruta `$default` si está disponible. Si no se ha definido la ruta `$default`, API Gateway devuelve un error.

## Configuración de rutas para una API de WebSocket en API Gateway
<a name="apigateway-websocket-api-routes"></a>

La primera vez que se crea una API de WebSocket, existen tres rutas predefinidas: `$connect`, `$disconnect` y `$default`. Puede crearlas mediante la consola, la API o la AWS CLI. Si lo desea, puede crear rutas personalizadas. Para obtener más información, consulte [Descripción general de las API de WebSocket en API Gateway](apigateway-websocket-api-overview.md).

**nota**  
En la CLI, puede crear las rutas antes o después de crear las integraciones y puede volver a utilizar la misma integración para varias rutas.

### Creación de una ruta mediante la consola de API Gateway
<a name="apigateway-websocket-api-route-using-console"></a>

**Para crear una ruta mediante la consola de API Gateway**

1. Inicie sesión en la consola de API Gateway, elija la API y, a continuación, elija **Routes (Rutas)**.

1. Elija **Crear ruta**.

1. En **Clave de la ruta**, ingrese el nombre de la clave de la ruta. Puede crear las rutas predefinidas (`$connect`, `$disconnect` y `$default`) o una ruta personalizada.
**nota**  
Cuando cree una ruta personalizada, no utilice el prefijo `$` en el nombre de la clave de ruta. Este prefijo está reservado para las rutas predefinidas.

1. Seleccione y configure el tipo de integración de la ruta. Para obtener más información, consulte [Configuración de una solicitud de integración de la API de WebSocket mediante la consola de API Gateway](apigateway-websocket-api-integration-requests.md#apigateway-websocket-api-integration-request-using-console).

### Creación de una ruta utilizando la AWS CLI
<a name="apigateway-websocket-api-route-using-awscli"></a>

El siguiente comando [create-route](https://docs.aws.amazon.com/cli/latest/reference/apigatewayv2/create-route.html) permite crear una ruta:

```
aws apigatewayv2 --region us-east-1 create-route --api-id aabbccddee --route-key $default
```

El resultado será similar al siguiente:

```
{
    "ApiKeyRequired": false,
    "AuthorizationType": "NONE",
    "RouteKey": "$default",
    "RouteId": "1122334"
}
```

### Especificación de los ajustes de la solicitud de ruta para `$connect`
<a name="apigateway-websocket-api-route-request-connect"></a>

Cuando se configura la ruta `$connect` para la API, están disponibles los siguientes ajustes opcionales para permitir la autorización para la API. Para obtener más información, consulte [La ruta `$connect`](apigateway-websocket-api-route-keys-connect-disconnect.md#apigateway-websocket-api-routes-about-connect).
+ **Authorization (Autorización)**: si no se necesita autorización, puede especificar `NONE`. De lo contrario, puede especificar: 
  + `AWS_IAM` para utilizar políticas estándar de AWS IAM con el fin de controlar el acceso a la API. 
  + `CUSTOM` para implementar la autorización para una API mediante la especificación de una función de autorizador de Lambda que se ha creado previamente. El autorizador puede encontrarse en su propia cuenta de AWS o en otra cuenta de AWS. Para obtener más información sobre los autorizadores de Lambda, consulte [Uso de autorizadores Lambda de API Gateway](apigateway-use-lambda-authorizer.md).
**nota**  
En la consola de API Gateway, la configuración de `CUSTOM` solo es visible después de que se haya configurado una función de autorizador como se describe en [Configuración de un autorizador de Lambda (consola)](configure-api-gateway-lambda-authorization.md#configure-api-gateway-lambda-authorization-with-console).
**importante**  
El valor de **Authorization (Autorización)** se aplica a toda la API, no solo a la ruta `$connect`. La ruta `$connect` protege a las demás rutas, porque se la llama en cada conexión.
+ **Clave de API obligatoria**: si lo desea, puede exigir el uso de una clave de API para la ruta `$connect` de una API. Puede utilizar las claves de API junto con los planes de uso para controlar y realizar un seguimiento del acceso a sus API. Para obtener más información, consulte [Planes de uso y clave de API para las API de REST en API Gateway](api-gateway-api-usage-plans.md).

### Configuración de la solicitud de ruta `$connect` con la consola API Gateway
<a name="apigateway-websocket-api-connect-route-request-using-console"></a>

Para configurar la solicitud de la ruta `$connect` para una API de WebSocket mediante la consola de API Gateway:

1. Inicie sesión en la consola de API Gateway, elija la API y, a continuación, elija **Routes (Rutas)**.

1. En **Rutas**, elija `$connect` o cree una ruta `$connect` según [Creación de una ruta mediante la consola de API Gateway](#apigateway-websocket-api-route-using-console).

1. En la sección **Configuración de la solicitud de ruta**, elija **Editar**.

1. En **Autorización**, seleccione un tipo de autorización.

1. Para solicitar una API para la ruta `$connect`, seleccione **Solicitar clave de API**.

1. Seleccione **Save changes (Guardar cambios)**.

# Configuración de respuestas de ruta para las API de WebSocket en API Gateway
<a name="apigateway-websocket-api-route-response"></a>

Las rutas de WebSocket se pueden configurar para la comunicación unidireccional o bidireccional. API Gateway no pasará la respuesta del backend a través de la respuesta de la ruta, a menos configure una respuesta de ruta. 

**nota**  
Solo puede definir la respuesta de la ruta `$default` para las API de WebSocket. Puede utilizar una respuesta de integración para manipular la respuesta de un servicio de backend. Para obtener más información, consulte [Información general sobre las respuestas de integración](apigateway-websocket-api-integration-responses.md#apigateway-websocket-api-integration-response-overview). 

Puede configurar respuestas de ruta y expresiones de selección de respuestas mediante la consola de API Gateway o la AWS CLI o un AWS SDK. 

Para obtener más información sobre las expresiones de selección de respuesta de ruta, consulte [Expresiones de selección de respuesta de ruta](apigateway-websocket-api-selection-expressions.md#apigateway-websocket-api-route-response-selection-expressions).

**Topics**
+ [Configurar una respuesta de ruta mediante la consola de API Gateway](#apigateway-websocket-api-route-response-using-console)
+ [Configuración de una respuesta de ruta con la AWS CLI](#apigateway-websocket-api-route-response-using-awscli)

## Configurar una respuesta de ruta mediante la consola de API Gateway
<a name="apigateway-websocket-api-route-response-using-console"></a>

Tras crear una API de WebSocket y asociar una función de Lambda proxy a la ruta predeterminada, puede configurar la respuesta de la ruta mediante la consola de API Gateway:

1. Inicie sesión en la consola de API Gateway y elija una API de WebSocket con una integración de función de Lambda de proxy en la ruta `$default`.

1. En **Routes** (Rutas), elija la ruta `$default`.

1. Elija **Habilitar la comunicación bidireccional**. 

1. Elija **Implementar API**.

1. Implemente su API en una etapa.

 Use el siguiente comando [wscat](https://www.npmjs.com/package/wscat) para conectarse a la API. Para obtener más información acerca de `wscat`, consulte [Utilice `wscat` para conectarse y enviar mensajes a una API de WebSocket](apigateway-how-to-call-websocket-api-wscat.md). 

```
wscat -c wss://api-id.execute-api.us-east-2.amazonaws.com/test
```

 Pulse el botón Enter para llamar a la ruta predeterminada. El cuerpo de la función de Lambda debería regresar.

## Configuración de una respuesta de ruta con la AWS CLI
<a name="apigateway-websocket-api-route-response-using-awscli"></a>

El siguiente comando [create-route-response](https://docs.aws.amazon.com/cli/latest/reference/apigatewayv2/create-route-response.html) permite crear una respuesta de ruta para la ruta `$default`. Puede identificar el ID de la API y el ID de ruta con los comandos [get-apis](https://docs.aws.amazon.com/cli/latest/reference/apigatewayv2/get-apis.html) y [get-routes](https://docs.aws.amazon.com/cli/latest/reference/apigatewayv2/get-routes.html).

```
aws apigatewayv2 create-route-response \
    --api-id aabbccddee \
    --route-id 1122334  \
    --route-response-key '$default'
```

El resultado será similar al siguiente:

```
{
    "RouteResponseId": "abcdef",
    "RouteResponseKey": "$default"
}
```

# Configuración de una ruta `$connect` que requiere un subprotocolo WebSocket
<a name="websocket-connect-route-subprotocol"></a>

Los clientes pueden usar el campo `Sec-WebSocket-Protocol` para solicitar un [subprotocolo WebSocket](https://datatracker.ietf.org/doc/html/rfc6455#page-12) durante la conexión a su API de WebSocket. Puede configurar una integración de la ruta `$connect` para permitir conexiones solo si un cliente solicita un subprotocolo compatible con su API.

La siguiente función de Lambda de ejemplo devuelve el encabezado `Sec-WebSocket-Protocol` a los clientes. La función establece una conexión a su API solo si el cliente especifica el subprotocolo `myprotocol`.

Para obtener una plantilla de CloudFormation que cree este ejemplo de integración de API y proxy de Lambda, consulte [samples/ws-subprotocol.zip](samples/ws-subprotocol.zip).

```
export const handler = async (event) => {
    if (event.headers != undefined) {
        const headers = toLowerCaseProperties(event.headers);
        
        if (headers['sec-websocket-protocol'] != undefined) {
            const subprotocolHeader = headers['sec-websocket-protocol'];
            const subprotocols = subprotocolHeader.split(',');
            
            if (subprotocols.indexOf('myprotocol') >= 0) {
                const response = {
                    statusCode: 200,
                    headers: {
                        "Sec-WebSocket-Protocol" : "myprotocol"
                    }
                };
                return response;
            }
        }
    }
    
    const response = {
        statusCode: 400
    };
        
    return response;
};

function toLowerCaseProperties(obj) {
    var wrapper = {};
    for (var key in obj) {
        wrapper[key.toLowerCase()] = obj[key];
    }
    return wrapper;
}
```

Puede usar [https://www.npmjs.com/package/wscat](https://www.npmjs.com/package/wscat) para probar si su API permite conexiones solo si un cliente solicita un subprotocolo compatible con su API. Los siguientes comandos utilizan el indicador `-s` para especificar subprotocolos durante la conexión.

El siguiente comando intenta una conexión con un subprotocolo no compatible. Dado que el cliente especificó el subprotocolo `chat1`, la integración de Lambda devuelve un error 400 y la conexión no es correcta.

```
wscat -c wss://api-id.execute-api.region.amazonaws.com/beta -s chat1
error: Unexpected server response: 400
```

El siguiente comando incluye un subprotocolo admitido en la solicitud de conexión. La integración de Lambda permite la conexión.

```
wscat -c wss://api-id.execute-api.region.amazonaws.com/beta -s chat1,myprotocol
connected (press CTRL+C to quit)
```

Para obtener más información acerca de cómo invocar la API de WebSocket, consulte [Invocación de las API de WebSocket](apigateway-how-to-call-websocket-api.md).

# Control y administración del acceso a las API de WebSocket en API Gateway
<a name="apigateway-websocket-api-control-access"></a>

API Gateway ofrece diversos mecanismos para controlar y administrar el acceso a su API de WebSocket.

Puede utilizar los siguientes mecanismos para realizar la autenticación y autorización:
+ **Los roles y las políticas estándar de AWS IAM** ofrecen controles de acceso flexibles y robustos. Puede usar roles y políticas de IAM para controlar quién puede crear y administrar sus API, así como quién puede invocarlas. Para obtener más información, consulte [Control del acceso a las API de WebSocket con autorización de IAM](apigateway-websocket-control-access-iam.md).
+ Las **etiquetas de IAM** se pueden utilizar con políticas de IAM para controlar el acceso. Para obtener más información, consulte [Uso de etiquetas para controlar el acceso a los recursos API de REST de API Gateway](apigateway-tagging-iam-policy.md).
+ Los **autorizadores de Lambda** son funciones Lambda que controlan el acceso a las API. Para obtener más información, consulte [Control del acceso a las API de WebSocket con autorizadores REQUEST de AWS Lambda](apigateway-websocket-api-lambda-auth.md).

Para aumentar la seguridad, le recomendamos que configure un autorizador para la ruta de `$connect` en todas las API de WebSocket. Es probable que deba hacerlo para asegurar el cumplimiento con diversos marcos normativos. Para obtener más información, consulte [Controles de Amazon API Gateway](https://docs.aws.amazon.com/securityhub/latest/userguide/apigateway-controls.html) en la *Guía del usuario de AWS Security Hub*.

**Topics**
+ [Control del acceso a las API de WebSocket con autorización de IAM](apigateway-websocket-control-access-iam.md)
+ [Control del acceso a las API de WebSocket con autorizadores REQUEST de AWS Lambda](apigateway-websocket-api-lambda-auth.md)

# Control del acceso a las API de WebSocket con autorización de IAM
<a name="apigateway-websocket-control-access-iam"></a>

La autorización de IAM en las API de WebSocket es similar a la de las [API REST](api-gateway-control-access-using-iam-policies-to-invoke-api.md), con las siguientes excepciones:
+ La acción `execute-api` admite `ManageConnections` además de las acciones existentes (`Invoke`, `InvalidateCache`). `ManageConnections` controla el acceso a la API @connections.
+ Las rutas de WebSocket utilizan un formato de ARN distinto:

  ```
  arn:aws:execute-api:region:account-id:api-id/stage-name/route-key
  ```
+ La API `@connections` utiliza el mismo formato de ARN que las API de REST:

  ```
  arn:aws:execute-api:region:account-id:api-id/stage-name/POST/@connections
  ```

**importante**  
Cuando utilice la [Autorización de IAM](#apigateway-websocket-control-access-iam), deberá firmar las solicitudes con [Signature Version 4 (SigV4)](https://docs.aws.amazon.com/IAM/latest/UserGuide/create-signed-request.html).

Por ejemplo, podría configurar la siguiente política en el cliente. Este ejemplo permite a cualquier usuario enviar un mensaje (`Invoke`) a todas las rutas excepto a una ruta secreta en la etapa `prod` e impide que se manden mensajes a los clientes conectados (`ManageConnections`) en todas las etapas.

------
#### [ JSON ]

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "execute-api:Invoke"
            ],
            "Resource": [
                "arn:aws:execute-api:us-east-1:111122223333:api-id/prod/*"
            ]
        },
        {
            "Effect": "Deny",
            "Action": [
                "execute-api:Invoke"
            ],
            "Resource": [
                "arn:aws:execute-api:us-east-1:111122223333:api-id/prod/secret"
            ]
        },
        {
            "Effect": "Deny",
            "Action": [
                "execute-api:ManageConnections"
            ],
            "Resource": [
                "arn:aws:execute-api:us-east-1:111122223333:api-id/*"
            ]
        }
    ]
}
```

------

# Control del acceso a las API de WebSocket con autorizadores REQUEST de AWS Lambda
<a name="apigateway-websocket-api-lambda-auth"></a>

La función de autorizador de Lambda en las API de WebSocket es similar a la de las [API de REST](apigateway-use-lambda-authorizer.md#api-gateway-lambda-authorizer-lambda-function-create), con las siguientes excepciones:
+  Solo puede utilizar una función de autorizador de Lambda para la ruta `$connect`. 
+ No se pueden utilizar variables de ruta (`event.pathParameters`), ya que la ruta es fija.
+ `event.methodArn` es diferente de su equivalente en la API de REST, ya que no tiene ningún método HTTP. En el caso de `$connect`, `methodArn` termina por `"$connect"`:

  ```
  arn:aws:execute-api:region:account-id:api-id/stage-name/$connect
  ```
+ Las variables de contexto de `event.requestContext` son diferentes de las de las API de REST.

 En el siguiente ejemplo se muestra una entrada a un autorizador `REQUEST` para una API de WebSocket:

```
{
    "type": "REQUEST",
    "methodArn": "arn:aws:execute-api:us-east-1:123456789012:abcdef123/default/$connect",
    "headers": {
        "Connection": "upgrade",
        "content-length": "0",
        "HeaderAuth1": "headerValue1",
        "Host": "abcdef123.execute-api.us-east-1.amazonaws.com",
        "Sec-WebSocket-Extensions": "permessage-deflate; client_max_window_bits",
        "Sec-WebSocket-Key": "...",
        "Sec-WebSocket-Version": "13",
        "Upgrade": "websocket",
        "X-Amzn-Trace-Id": "...",
        "X-Forwarded-For": "...",
        "X-Forwarded-Port": "443",
        "X-Forwarded-Proto": "https"
    },
    "multiValueHeaders": {
        "Connection": [
            "upgrade"
        ],
        "content-length": [
            "0"
        ],
        "HeaderAuth1": [
            "headerValue1"
        ],
        "Host": [
            "abcdef123.execute-api.us-east-1.amazonaws.com"
        ],
        "Sec-WebSocket-Extensions": [
            "permessage-deflate; client_max_window_bits"
        ],
        "Sec-WebSocket-Key": [
            "..."
        ],
        "Sec-WebSocket-Version": [
            "13"
        ],
        "Upgrade": [
            "websocket"
        ],
        "X-Amzn-Trace-Id": [
            "..."
        ],
        "X-Forwarded-For": [
            "..."
        ],
        "X-Forwarded-Port": [
            "443"
        ],
        "X-Forwarded-Proto": [
            "https"
        ]
    },
    "queryStringParameters": {
        "QueryString1": "queryValue1"
    },
    "multiValueQueryStringParameters": {
        "QueryString1": [
            "queryValue1"
        ]
    },
    "stageVariables": {},
    "requestContext": {
        "routeKey": "$connect",
        "eventType": "CONNECT",
        "extendedRequestId": "...",
        "requestTime": "19/Jan/2023:21:13:26 +0000",
        "messageDirection": "IN",
        "stage": "default",
        "connectedAt": 1674162806344,
        "requestTimeEpoch": 1674162806345,
        "identity": {
            "sourceIp": "..."
        },
        "requestId": "...",
        "domainName": "abcdef123.execute-api.us-east-1.amazonaws.com",
        "connectionId": "...",
        "apiId": "abcdef123"
    }
}
```

El siguiente ejemplo de función de autorizador de Lambda es una versión de WebSocket de la función de autorizador de Lambda para las API de REST de la sección [Ejemplos adicionales de funciones del autorizador de Lambda](apigateway-use-lambda-authorizer.md#api-gateway-lambda-authorizer-lambda-function-create):

------
#### [ Node.js ]

```
   // A simple REQUEST authorizer example to demonstrate how to use request 
   // parameters to allow or deny a request. In this example, a request is  
   // authorized if the client-supplied HeaderAuth1 header and QueryString1 query parameter
   // in the request context match the specified values of
   // of 'headerValue1' and 'queryValue1' respectively.
            export const handler = function(event, context, callback) {
    console.log('Received event:', JSON.stringify(event, null, 2));

   // Retrieve request parameters from the Lambda function input:
   var headers = event.headers;
   var queryStringParameters = event.queryStringParameters;
   var stageVariables = event.stageVariables;
   var requestContext = event.requestContext;
       
   // Parse the input for the parameter values
   var tmp = event.methodArn.split(':');
   var apiGatewayArnTmp = tmp[5].split('/');
   var awsAccountId = tmp[4];
   var region = tmp[3];
   var ApiId = apiGatewayArnTmp[0];
   var stage = apiGatewayArnTmp[1];
   var route = apiGatewayArnTmp[2];
       
   // Perform authorization to return the Allow policy for correct parameters and 
   // the 'Unauthorized' error, otherwise.
   var authResponse = {};
   var condition = {};
    condition.IpAddress = {};
    
   if (headers.HeaderAuth1 === "headerValue1"
       && queryStringParameters.QueryString1 === "queryValue1") {
        callback(null, generateAllow('me', event.methodArn));
    }  else {
        callback(null, generateDeny('me', event.methodArn)); 
    }
}
    
// Helper function to generate an IAM policy
var generatePolicy = function(principalId, effect, resource) {
   // Required output:
   var authResponse = {};
    authResponse.principalId = principalId;
   if (effect && resource) {
       var policyDocument = {};
        policyDocument.Version = '2012-10-17		 	 	 '; // default version
       policyDocument.Statement = [];
       var statementOne = {};
        statementOne.Action = 'execute-api:Invoke'; // default action
       statementOne.Effect = effect;
        statementOne.Resource = resource;
        policyDocument.Statement[0] = statementOne;
        authResponse.policyDocument = policyDocument;
    }
   // Optional output with custom properties of the String, Number or Boolean type.
   authResponse.context = {
       "stringKey": "stringval",
       "numberKey": 123,
       "booleanKey": true
    };
   return authResponse;
}
    
var generateAllow = function(principalId, resource) {
   return generatePolicy(principalId, 'Allow', resource);
}
    
var generateDeny = function(principalId, resource) {
   return generatePolicy(principalId, 'Deny', resource);
}
```

------
#### [ Python ]

```
# A simple REQUEST authorizer example to demonstrate how to use request
# parameters to allow or deny a request. In this example, a request is
# authorized if the client-supplied HeaderAuth1 header and QueryString1 query parameter
# in the request context match the specified values of
# of 'headerValue1' and 'queryValue1' respectively.

import json


def lambda_handler(event, context):
    print(event)

    # Retrieve request parameters from the Lambda function input:
    headers = event['headers']
    queryStringParameters = event['queryStringParameters']
    stageVariables = event['stageVariables']
    requestContext = event['requestContext']

    # Parse the input for the parameter values
    tmp = event['methodArn'].split(':')
    apiGatewayArnTmp = tmp[5].split('/')
    awsAccountId = tmp[4]
    region = tmp[3]
    ApiId = apiGatewayArnTmp[0]
    stage = apiGatewayArnTmp[1]
    route = apiGatewayArnTmp[2]

    # Perform authorization to return the Allow policy for correct parameters
    # and the 'Unauthorized' error, otherwise.

    authResponse = {}
    condition = {}
    condition['IpAddress'] = {}

    if (headers['HeaderAuth1'] ==
            "headerValue1" and queryStringParameters["QueryString1"] == "queryValue1"):
        response = generateAllow('me', event['methodArn'])
        print('authorized')
        return json.loads(response)
    else:
        response = generateDeny('me', event['methodArn'])
        print('unauthorized')
        return json.loads(response)

    # Help function to generate IAM policy


def generatePolicy(principalId, effect, resource):
    authResponse = {}
    authResponse['principalId'] = principalId
    if (effect and resource):
        policyDocument = {}
        policyDocument['Version'] = '2012-10-17		 	 	 '
        policyDocument['Statement'] = []
        statementOne = {}
        statementOne['Action'] = 'execute-api:Invoke'
        statementOne['Effect'] = effect
        statementOne['Resource'] = resource
        policyDocument['Statement'] = [statementOne]
        authResponse['policyDocument'] = policyDocument

    authResponse['context'] = {
        "stringKey": "stringval",
        "numberKey": 123,
        "booleanKey": True
    }

    authResponse_JSON = json.dumps(authResponse)

    return authResponse_JSON


def generateAllow(principalId, resource):
    return generatePolicy(principalId, 'Allow', resource)


def generateDeny(principalId, resource):
    return generatePolicy(principalId, 'Deny', resource)
```

------

Para configurar la función de Lambda anterior como una función de autorizador `REQUEST` para una API de WebSocket, siga el mismo procedimiento que para las [API de REST](configure-api-gateway-lambda-authorization.md#configure-api-gateway-lambda-authorization-with-console).

Para configurar la ruta `$connect` de forma que utilice este autorizador de Lambda en la consola, seleccione o cree la ruta `$connect`. En la sección **Configuración**, elija **Editar**. Seleccione su autorizador en el menú desplegable **Autorización** y, a continuación, elija **Guardar cambios**.

Para probar el autorizador, tiene que crear una conexión nueva. El cambio de autorizador en `$connect` no afecta a los clientes que ya están conectados. Al conectarse a la API de WebSocket, tiene que proporcionar valores para todas las fuentes de identidad configuradas. Por ejemplo, puede conectarse enviando una cadena de consulta y un encabezado válidos mediante `wscat`, como se muestra en el siguiente ejemplo:

```
wscat -c 'wss://myapi.execute-api.us-east-1.amazonaws.com/beta?QueryString1=queryValue1' -H HeaderAuth1:headerValue1
```

Si intenta conectarse sin un valor de identidad válido, recibirá una respuesta `401`:

```
wscat -c wss://myapi.execute-api.us-east-1.amazonaws.com/beta
error: Unexpected server response: 401
```

# Integraciones de API de WebSocket en API Gateway
<a name="apigateway-websocket-api-integrations"></a>

Una vez configurada una ruta de API, debe integrarlo con un punto de conexión en el backend. El punto de conexión del backend también se conoce como punto de conexión de integración y puede ser una función de Lambda, un punto de conexión HTTP o una acción del servicio de AWS. a integración de la API tiene una solicitud de integración y una respuesta de integración.

En esta sección, puede aprender a configurar solicitudes de integración y respuestas de integración para su API de WebSocket. 

**Topics**
+ [Configuración de una solicitud de integración de API de WebSocket en API Gateway](apigateway-websocket-api-integration-requests.md)
+ [Configuración de una respuesta de integración de API de WebSocket en API Gateway](apigateway-websocket-api-integration-responses.md)

# Configuración de una solicitud de integración de API de WebSocket en API Gateway
<a name="apigateway-websocket-api-integration-requests"></a>

La configuración de una solicitud de integración implica lo siguiente:
+ Elegir una clave de ruta para integrarla en el backend.
+ Especificación del punto de conexión de backend que se va a invocar. Las API de WebSocket admiten los siguientes tipos de integración:
  + `AWS_PROXY`
  + `AWS`
  + `HTTP_PROXY`
  + `HTTP`
  + `MOCK`

  Para obtener más información sobre los tipos de integración, consulte [IntegrationType](https://docs.aws.amazon.com/apigatewayv2/latest/api-reference/apis-apiid-integrations-integrationid.html#apis-apiid-integrations-integrationid-prop-integration-integrationtype) en la API de REST de API Gateway V2.
+ Configurar cómo transformar los datos de la solicitud de ruta, si fuera necesario, en datos de solicitud de integración mediante la especificación de una o varias plantillas de solicitud.

## Configuración de una solicitud de integración de la API de WebSocket mediante la consola de API Gateway
<a name="apigateway-websocket-api-integration-request-using-console"></a>

**Para agregar una solicitud de integración a una ruta en una API de WebSocket mediante la consola de API Gateway**

1. Inicie sesión en la consola de API Gateway, elija la API y, a continuación, elija **Routes (Rutas)**.

1. En **Routes (Rutas)**, elija la ruta.

1. Elija la pestaña **Solicitud de integración** y, a continuación, en la sección **Configuración de solicitud de integración**, elija **Editar**.

1. En **Tipo de integración**, seleccione una de las siguientes opciones:
   + Elija **Función de Lambda** solo si la API se va a integrar con una función de AWS Lambda que ya ha creado en esta cuenta o en otra.

     Para crear una nueva función de Lambda en AWS Lambda, establecer un permiso a nivel de recursos en la función de Lambda o realizar cualquier otra acción de servicio Lambda, elija **Servicio de AWS** en su lugar.
   + Elija **HTTP** si la API se va a integrar con un punto de conexión HTTP existente. Para obtener más información, consulte [Integraciones de HTTP para las API de REST en API Gateway](setup-http-integrations.md).
   + Elija **Mock (Simulación)** si desea generar respuestas de la API directamente a partir de API Gateway, sin necesidad de un backend de integración. Para obtener más información, consulte [Simulación de integraciones para las API de REST en API Gateway](how-to-mock-integration.md).
   + Elija **Servicio de AWS** si la API se va a integrar directamente con un servicio de AWS.
   + Elija **Enlace de VPC** si la API va a utilizar un `VpcLink` como un punto de conexión de integración privada. Para obtener más información, consulte [Configuración de una integración privada](set-up-private-integration.md).

1. Si elige **Función de Lambda**, proceda de la forma siguiente:

   1. En **Usar la integración de proxy Lambda**, elija la casilla si piensa usar la [Integración de proxy Lambda](set-up-lambda-proxy-integrations.md#api-gateway-create-api-as-simple-proxy) o la [Integración de proxy Lambda entre cuentas](apigateway-cross-account-lambda-integrations.md).

   1. En **Función de Lambda**, especifique la función de una de las siguientes formas:
      + Si la función de Lambda está en la misma cuenta, ingrese el nombre de la función y, a continuación, seleccione la función de la lista desplegable.
**nota**  
Si lo desea, el nombre de la función puede incluir su alias o especificación de versión, como en `HelloWorld`, `HelloWorld:1` o `HelloWorld:alpha`.
      + Si la función se encuentra en una cuenta diferente, escriba el ARN de la función.

   1. Si desea utilizar el valor predeterminado del tiempo de espera, que es de 29 segundos, mantenga activado el **Tiempo de espera predeterminado**. Para establecer un tiempo de espera personalizado, elija **Tiempo de espera predeterminado** e ingrese un valor de tiempo de espera comprendido entre `50` y `29000` milisegundos.

1. Si ha elegido **HTTP**, siga las instrucciones del paso 4 que figuran en [Configuración de una solicitud de integración de la API mediante la consola de API Gateway](how-to-method-settings-console.md).

1. Si ha elegido **Mock (Simulación)**, continúe con el paso **Request Templates (Plantillas de solicitud)**.

1. Si elige **Servicio de AWS**, siga las instrucciones del paso 6 que figuran en [Configuración de una solicitud de integración de la API mediante la consola de API Gateway](how-to-method-settings-console.md).

1. Si elige **Enlace de VPC**, haga lo siguiente:

   1. En **Integración de proxy VPC**, elija la casilla si desea que sus solicitudes se transfieran por proxy al punto de conexión del `VPCLink`.

   1. En **HTTP method (Método HTTP)**, elija el tipo de método HTTP que más se parezca al método del backend HTTP.

   1. En la lista desplegable **Enlace de VPC**, seleccione un enlace de VPC. Puede seleccionar `[Use Stage Variables]` e ingresar **\$1\$1stageVariables.vpcLinkId\$1** en el cuadro de texto situado debajo de la lista.

      Puede definir la variable de etapa `vpcLinkId` después de implementar la API en una etapa y establecer su valor en el ID del `VpcLink`.

   1. En **URL del punto de conexión**, escriba la dirección URL del backend HTTP que desea que utilice esta integración.

   1. Si desea utilizar el valor predeterminado del tiempo de espera, que es de 29 segundos, mantenga activado el **Tiempo de espera predeterminado**. Para establecer un tiempo de espera personalizado, elija **Tiempo de espera predeterminado** e ingrese un valor de tiempo de espera comprendido entre `50` y `29000` milisegundos.

1. Elija **Guardar cambios**.

1. En **Plantillas de solicitud**, haga lo siguiente:

   1. Para ingresar una **Expresión de selección de plantillas**, en **Plantillas de solicitud**, elija **Editar**.

   1. Ingrese una **Expresión de selección de plantillas**. Use una expresión que API Gateway busque en la carga del mensaje. Si la encuentra, se evalúa y el resultado es un valor de clave de plantilla que se utiliza para seleccionar la plantilla de asignación de datos que debe aplicarse a los datos de la carga del mensaje. En el siguiente paso se crea la plantilla de mapeo de datos. Elija **Editar** para guardar los cambios.

   1. Elija **Crear plantilla** para crear la plantilla de mapeo de datos. En **Clave de plantilla**, ingrese el valor de clave de plantilla que se utiliza para seleccionar la plantilla de mapeo de datos que debe aplicarse a los datos de la carga del mensaje. A continuación, ingrese una plantilla de mapeo. Seleccione **Crear plantilla**.

      Para obtener información sobre las expresiones de selección de plantillas, consulte [Expresiones de selección de plantilla](websocket-api-data-transformations.md#apigateway-websocket-api-template-selection-expressions).

## Configurar una solicitud de integración mediante la AWS CLI
<a name="apigateway-websocket-api-integration-request-using-awscli"></a>

Puede utilizar la AWS CLI para configurar una solicitud de integración para una ruta en una API de WebSocket tal y como se muestra en el siguiente ejemplo, que crea una integración simulada:

1. Cree un archivo denominado `integration-params.json` con el siguiente contenido:

   ```
   {"PassthroughBehavior": "WHEN_NO_MATCH", "TimeoutInMillis": 29000, "ConnectionType": "INTERNET", "RequestTemplates": {"application/json": "{\"statusCode\":200}"}, "IntegrationType": "MOCK"}
   ```

1. El siguiente comando [create-integration](https://docs.aws.amazon.com/cli/latest/reference/apigatewayv2/create-integration.html) permite crear la integración simulada.

   ```
   aws apigatewayv2 --region us-east-1 create-integration --api-id aabbccddee --cli-input-json file://integration-params.json
   ```

   El resultado será similar al siguiente:

   ```
   {
       "PassthroughBehavior": "WHEN_NO_MATCH",
       "TimeoutInMillis": 29000,
       "ConnectionType": "INTERNET",
       "IntegrationResponseSelectionExpression": "${response.statuscode}",
       "RequestTemplates": {
           "application/json": "{\"statusCode\":200}"
       },
       "IntegrationId": "0abcdef",
       "IntegrationType": "MOCK"
   }
   ```

También puede configurar una solicitud de integración para una integración de proxy mediante la AWS CLI.

1. Cree una función de Lambda en la consola de Lambda y asígnela un rol de ejecución de funciones Lambda básico.

1. Use el siguiente comando [create-integration](https://docs.aws.amazon.com/cli/latest/reference/apigatewayv2/create-integration.html) para crear la integración.

   ```
   aws apigatewayv2 create-integration --api-id aabbccddee --integration-type AWS_PROXY --integration-method POST --integration-uri arn:aws:apigateway:us-east-1:lambda:path/2015-03-31/functions/arn:aws:lambda:us-east-1:123412341234:function:simpleproxy-echo-e2e/invocations
   ```

El resultado será similar al siguiente:

```
{
    "PassthroughBehavior": "WHEN_NO_MATCH",
    "IntegrationMethod": "POST",
    "TimeoutInMillis": 29000,
    "ConnectionType": "INTERNET",
    "IntegrationUri": "arn:aws:apigateway:us-east-1:lambda:path/2015-03-31/functions/arn:aws:lambda:us-east-1:123412341234:function:simpleproxy-echo-e2e/invocations",
    "IntegrationId": "abcdefg",
    "IntegrationType": "AWS_PROXY"
}
```

## Formato de entrada de una función de Lambda para la integración de proxy para API de WebSocket
<a name="api-gateway-simple-proxy-for-lambda-input-format-websocket"></a>

Con la integración de proxy de Lambda, API Gateway asigna toda la solicitud de cliente al parámetro de entrada `event` de la función de Lambda del backend. En el siguiente ejemplo se muestra la estructura del evento de entrada de la ruta `$connect` y el evento de entrada de la ruta `$disconnect` que API Gateway envía a una integración de proxy de Lambda.

------
#### [ Input from the \$1connect route ]

```
{
    headers: {
      Host: 'abcd123.execute-api.us-east-1.amazonaws.com',
      'Sec-WebSocket-Extensions': 'permessage-deflate; client_max_window_bits',
      'Sec-WebSocket-Key': '...',
      'Sec-WebSocket-Version': '13',
      'X-Amzn-Trace-Id': '...',
      'X-Forwarded-For': '192.0.2.1',
      'X-Forwarded-Port': '443',
      'X-Forwarded-Proto': 'https'
    },
    multiValueHeaders: {
      Host: [ 'abcd123.execute-api.us-east-1.amazonaws.com' ],
      'Sec-WebSocket-Extensions': [ 'permessage-deflate; client_max_window_bits' ],
      'Sec-WebSocket-Key': [ '...' ],
      'Sec-WebSocket-Version': [ '13' ],
      'X-Amzn-Trace-Id': [ '...' ],
      'X-Forwarded-For': [ '192.0.2.1' ],
      'X-Forwarded-Port': [ '443' ],
      'X-Forwarded-Proto': [ 'https' ]
    },
    requestContext: {
      routeKey: '$connect',
      eventType: 'CONNECT',
      extendedRequestId: 'ABCD1234=',
      requestTime: '09/Feb/2024:18:11:43 +0000',
      messageDirection: 'IN',
      stage: 'prod',
      connectedAt: 1707502303419,
      requestTimeEpoch: 1707502303420,
      identity: { sourceIp: '192.0.2.1' },
      requestId: 'ABCD1234=',
      domainName: 'abcd1234.execute-api.us-east-1.amazonaws.com',
      connectionId: 'AAAA1234=',
      apiId: 'abcd1234'
    },
    isBase64Encoded: false
  }
```

------
#### [ Input from the \$1disconnect route ]

```
{
    headers: {
      Host: 'abcd1234.execute-api.us-east-1.amazonaws.com',
      'x-api-key': '',
      'X-Forwarded-For': '',
      'x-restapi': ''
    },
    multiValueHeaders: {
      Host: [ 'abcd1234.execute-api.us-east-1.amazonaws.com' ],
      'x-api-key': [ '' ],
      'X-Forwarded-For': [ '' ],
      'x-restapi': [ '' ]
    },
    requestContext: {
      routeKey: '$disconnect',
      disconnectStatusCode: 1005,
      eventType: 'DISCONNECT',
      extendedRequestId: 'ABCD1234=',
      requestTime: '09/Feb/2024:18:23:28 +0000',
      messageDirection: 'IN',
      disconnectReason: 'Client-side close frame status not set',
      stage: 'prod',
      connectedAt: 1707503007396,
      requestTimeEpoch: 1707503008941,
      identity: { sourceIp: '192.0.2.1' },
      requestId: 'ABCD1234=',
      domainName: 'abcd1234.execute-api.us-east-1.amazonaws.com',
      connectionId: 'AAAA1234=',
      apiId: 'abcd1234'
    },
    isBase64Encoded: false
  }
```

------

# Configuración de una respuesta de integración de API de WebSocket en API Gateway
<a name="apigateway-websocket-api-integration-responses"></a>

En la siguiente sección se proporciona una breve información general de las respuestas de integración para la API de WebSocket y cómo configurar una respuesta de integración para una API de WebSocket. 

**Topics**
+ [Información general sobre las respuestas de integración](#apigateway-websocket-api-integration-response-overview)
+ [Respuestas de integración para la comunicación bidireccional](#apigateway-websocket-api-integration-response-for-two-way-communication)
+ [Configuración de una respuesta de integración mediante la consola de API Gateway](#apigateway-websocket-api-integration-response-using-console)
+ [Configurar una respuesta de integración mediante la AWS CLI](#apigateway-websocket-api-integration-response-using-awscli)

## Información general sobre las respuestas de integración
<a name="apigateway-websocket-api-integration-response-overview"></a>

La respuesta de integración de API Gateway es una manera de modelar y manipular la respuesta desde un servicio de backend. Existen algunas diferencias en la configuración de una API de REST frente a la de una respuesta de integración de API de WebSocket, pero conceptualmente el comportamiento es el mismo.

Las rutas de WebSocket se pueden configurar para la comunicación unidireccional o bidireccional.
+ Cuando una ruta se configura para la comunicación bidireccional, una respuesta de integración le permite configurar transformaciones de la carga del mensaje que se devuelve, de forma similar a las respuestas de integración para las API de REST.
+ Si una ruta se configura para la comunicación unidireccional, independientemente de la configuración de respuesta de integración, no se devolverá ninguna respuesta a través del canal de WebSocket una vez procesado el mensaje.

 API Gateway no pasará la respuesta del backend a través de la respuesta de la ruta, a menos configure una respuesta de ruta. Para obtener más información sobre cómo configurar una respuesta de ruta, consulte [Configuración de respuestas de ruta para las API de WebSocket en API Gateway](apigateway-websocket-api-route-response.md).

## Respuestas de integración para la comunicación bidireccional
<a name="apigateway-websocket-api-integration-response-for-two-way-communication"></a>

Las integraciones se pueden dividir en integraciones de *proxy* e integraciones *que no son de proxy*.

**importante**  
En las *integraciones de proxy*, API Gateway pasa automáticamente la salida del backend al intermediario como la carga completa. No hay ninguna respuesta de integración.

En las *integraciones que no son de proxy*, es necesario configurar al menos una respuesta de integración:
+ Lo ideal sería que una de las respuestas de integración actuase como método catch-all cuando no se puede realizar ninguna elección explícita. Este caso predeterminado se representa mediante la configuración de la clave de respuesta de integración `$default`.
+ En el resto de los casos, la clave de respuesta de integración funciona como una expresión regular. Debe seguir el formato `"/expression/"`.

Para las integraciones HTTP que no sean de proxy:
+ API Gateway intentará emparejar el código de estado HTTP de la respuesta del backend. La clave de respuesta de integración funcionará como una expresión regular en este caso. Si no se encuentra una coincidencia, se elige `$default` como respuesta de integración.
+ La expresión de selección de plantillas, tal y como se describe anteriormente, funciona de forma idéntica. Por ejemplo:
  + `/2\d\d/`: recibe y transforma respuestas correctas
  + `/4\d\d/`: recibe y transforma errores de solicitud incorrecta
  + `$default`: recibe y transforma todas las respuestas inesperadas

Para obtener más información sobre las expresiones de selección de plantillas, consulte [Expresiones de selección de plantilla](websocket-api-data-transformations.md#apigateway-websocket-api-template-selection-expressions).

## Configuración de una respuesta de integración mediante la consola de API Gateway
<a name="apigateway-websocket-api-integration-response-using-console"></a>

Para configurar una respuesta de integración de ruta en una API de WebSocket mediante la consola de API Gateway:

1. Inicie sesión en la consola de API Gateway, en [https://console.aws.amazon.com/apigateway](https://console.aws.amazon.com/apigateway).

1.  Elija la API de WebSocket y elija la ruta.

1. Elija la pestaña **Solicitud de integración** y, a continuación, en la sección **Configuración de solicitud de integración**, elija **Crear respuesta de integración**.

1. En **Clave de respuesta**, introduzca un valor que se encontrará en la clave de respuesta que aparece en el mensaje saliente tras evaluar la expresión de selección de respuesta. Por ejemplo, puede ingresar **/4\$1d\$1d/** para recibir y transformar los errores de solicitudes erróneas o ingresar **\$1default** para recibir y transformar todas las respuestas que coincidan con la expresión de selección de plantillas. 

1. En **Expresión de selección de plantillas**, ingrese una expresión de selección para evaluar el mensaje saliente.

1. Elija **Crear respuesta**.

1. También puede definir una plantilla de mapeo para configurar las transformaciones de la carga útil de los mensajes devueltos. Seleccione **Crear plantilla**.

1. Ingrese un nombre de clave. Si elige la expresión de selección de plantillas predeterminada, ingrese **\$1\$1default**.

1. En **Plantilla de respuesta**, ingrese la plantilla de mapeo en el editor de código.

1. Seleccione **Crear plantilla**.

1. Elige **Implementar API** para implementar su API.

 Use el siguiente comando [wscat](https://www.npmjs.com/package/wscat) para conectarse a la API. Para obtener más información acerca de `wscat`, consulte [Utilice `wscat` para conectarse y enviar mensajes a una API de WebSocket](apigateway-how-to-call-websocket-api-wscat.md). 

```
wscat -c wss://api-id.execute-api.us-east-2.amazonaws.com/test
```

 Cuando llame a la ruta, la carga útil del mensaje devuelto debería regresar. 

## Configurar una respuesta de integración mediante la AWS CLI
<a name="apigateway-websocket-api-integration-response-using-awscli"></a>

El siguiente comando [create-integration-response](https://docs.aws.amazon.com/cli/latest/reference/apigatewayv2/create-integration-response.html) permite crear una respuesta de integración `$default`:

```
aws apigatewayv2 create-integration-response \
    --api-id vaz7da96z6 \
    --integration-id a1b2c3 \
    --integration-response-key '$default'
```

# Solicitud de la validación de las API de WebSocket en API Gateway
<a name="websocket-api-request-validation"></a>

Puede configurar API Gateway para que realice la validación en una solicitud de ruta antes de continuar con la solicitud de integración. Si la validación falla, API Gateway falla la solicitud sin llamar a su back-end, envía una respuesta de puerta de enlace "Cuerpo de solicitud incorrecto" al cliente y publica los resultados de validación en CloudWatch Logs. El uso de la validación de esta manera reduce las llamadas innecesarias a su back-end de API.

## Expresiones de selección de modelo
<a name="apigateway-websocket-api-model-selection-expressions"></a>

Puede utilizar una expresión de selección de modelo para validar dinámicamente solicitudes dentro de la misma ruta. La validación del modelo se produce si proporciona una expresión de selección de modelo para integraciones proxy o no proxy. Es posible que necesite definir el modelo de `$default` como una alternativa cuando no se encuentre ningún modelo coincidente. Si no hay ningún modelo coincidente y `$default` no está definido, la validación falla. La expresión de selección tiene el aspecto `Route.ModelSelectionExpression` y se evalúa como la clave para `Route.RequestModels`.

Al definir una ruta para una API de WebSocket, puede especificar si lo desea una *expresión de selección de modelo*. Esta expresión se evalúa para seleccionar el modelo que se utilizará para la validación del cuerpo cuando se reciba una solicitud. La expresión se evalúa en una de las entradas de la propiedad de una ruta [https://docs.aws.amazon.com/apigatewayv2/latest/api-reference/apis-apiid-routes.html#apis-apiid-routes-prop-route-requestmodels](https://docs.aws.amazon.com/apigatewayv2/latest/api-reference/apis-apiid-routes.html#apis-apiid-routes-prop-route-requestmodels).

Un modelo se expresa como un [esquema JSON](https://datatracker.ietf.org/doc/html/draft-zyp-json-schema-04) y describe la estructura de datos del cuerpo de la solicitud. La naturaleza de estas expresiones de selección le permite elegir de forma dinámica el modelo con el que debe realizarse la validación en tiempo de ejecución para una ruta determinada. Para obtener información sobre cómo crear un modelo, consulte [Modelos de datos para las API de REST](models-mappings-models.md). 

## Configuración de la validación de solicitudes mediante la consola de API Gateway
<a name="apigateway-websocket-api-model-selection-expression-example"></a>

En el siguiente ejemplo se muestra cómo configurar la validación de la solicitud en una ruta.

 En primer lugar, debe crear un modelo y, a continuación, crear una ruta. A continuación, debe configurar la validación de la solicitud en la ruta que acaba de crear. Por último, debe implementar y probar la API. Para completar este tutorial, necesita una API de WebSocket con `$request.body.action` como expresión de selección de rutas y un punto de conexión de integración para la nueva ruta.

También es necesario `wscat` para conectarse a la API. Para obtener más información, consulte [Utilice `wscat` para conectarse y enviar mensajes a una API de WebSocket](apigateway-how-to-call-websocket-api-wscat.md).

**Para crear un modelo**

1. Inicie sesión en la consola de API Gateway, en [https://console.aws.amazon.com/apigateway](https://console.aws.amazon.com/apigateway).

1. Elija una API de WebSocket.

1. En el panel de navegación principal, elija **Modelos**.

1. Seleccione **Crear modelo**.

1. En **Nombre**, escriba **emailModel**.

1. En **Tipo de contenido**, ingrese **application/json**.

1. En **Esquema del modelo**, escriba el siguiente modelo:

   ```
   {
       "$schema": "http://json-schema.org/draft-04/schema#",
       "type" : "object",
       "required" : [ "address"],
       "properties" : {
           "address": {
               "type": "string"
           }
       }
   }
   ```

   Este modelo requiere que la solicitud contenga una dirección de correo electrónico.

1. Seleccione **Save**.

En este paso, se crea una ruta para la API de WebSocket.

**Para crear una ruta**

1. En el panel de navegación principal, elija **Rutas**.

1. Elija **Create route (Crear ruta)**.

1. Para **Route key** (Clave de ruta), ingrese **sendMessage**.

1. Elija un tipo de integración y especifique un punto de conexión de integración. Para obtener más información consulte () [Integraciones de API de WebSocket en API Gateway](apigateway-websocket-api-integrations.md).

1. Elija **Create route (Crear ruta)**.

En este paso, debe configurar la validación de solicitudes para la ruta `sendMessage`.

**Configuración de la validación de solicitudes**

1. En la pestaña **Solicitud de ruta**, en **Configuración de solicitud de ruta**, elija **Editar**.

1. Para **Expresión de selección de modelo**, ingrese **\$1\$1request.body.messageType\$1**.

   API Gateway usa la propiedad `messageType` para validar la solicitud entrante.

1. Elija **Agregar modelo de solicitud**.

1. Para **Clave de modelo**, ingrese **email**.

1. Para **Modelo**, elija **emailModel**.

   API Gateway valida los mensajes entrantes con la propiedad `messageType` establecida en `email` frente a este modelo.
**nota**  
Si API Gateway no puede hacer coincidir la expresión de selección del modelo con una clave de modelo, selecciona el modelo `$default`. Si no hay ningún modelo `$default`, la validación produce un error. Para las API de producción, se recomienda crear un modelo `$default`.

1. Seleccione **Save changes (Guardar cambios)**.

En este paso, debe implementar y probar la API.

**Implementación y prueba de la API**

1. Elija **Implementar API**.

1. Elija la etapa que desee en el menú desplegable o escriba el nombre de una etapa nueva.

1. Elija **Implementar**.

1. En el panel de navegación principal, elija **Etapas**.

1. Copie la URL de WebSocket de la API. La dirección URL debe tener un aspecto similar al siguiente: `wss://abcdef123.execute-api.us-east-2.amazonaws.com/production`.

1. Abra un nuevo terminal y ejecute el comando **wscat** con los siguientes parámetros.

   ```
   wscat -c wss://abcdef123.execute-api.us-west-2.amazonaws.com/production
   ```

   ```
   Connected (press CTRL+C to quit)
   ```

1. Use el siguiente comando para probar la API.

   ```
   {"action": "sendMessage", "messageType": "email"}
   ```

   ```
   {"message": "Invalid request body", "connectionId":"ABCD1=234", "requestId":"EFGH="}
   ```

   API Gateway producirá un error en la solicitud.

   Use el siguiente comando para enviar una solicitud válida a la API.

   ```
   {"action": "sendMessage", "messageType": "email", "address": "mary_major@example.com"}
   ```

# Transformaciones de datos para las API de WebSocket en API Gateway
<a name="websocket-api-data-transformations"></a>

En API Gateway, una solicitud de método de API de WebSocket puede aceptar una carga en un formato diferente del de la carga de la solicitud de integración, según requiera el backend. Del mismo modo, el backend puede devolver una carga de respuesta de integración diferente de la carga de respuesta del método que espera el frontend. 

API Gateway le permite utilizar transformaciones de plantillas de asignación para asignar la carga útil de una solicitud de método a la solicitud de integración correspondiente y de una respuesta de integración a la respuesta de método correspondiente. Cree una plantilla de asignación y especifique una expresión de selección de plantilla para determinar qué plantilla se utilizará para realizar las transformaciones de datos necesarias.

Puede utilizar asignaciones de datos para asignar datos de una [solicitud de ruta](api-gateway-basic-concept.md#apigateway-definition-route-request) a una integración con backend. Para obtener más información, consulte [Configuración de asignación de datos para las API de WebSocket en API Gateway](websocket-api-data-mapping.md).

## Plantillas y modelos de asignación
<a name="apigateway-websocket-api-mapping-templats-and-models"></a>

 Una *plantilla de asignación* es un script expresado en [Velocity Template Language (VTL)](https://velocity.apache.org/engine/devel/vtl-reference.html) que se aplica a la carga mediante [expresiones JSONPath](https://goessner.net/articles/JsonPath/). Para obtener más información acerca de las plantillas de mapeo de API Gateway, consulte [Asignación de las transformaciones de plantillas de asignación para las API de REST en API Gateway](models-mappings.md).

La carga puede tener un *modelo de datos* de acuerdo con el [esquema JSON, borrador 4](https://datatracker.ietf.org/doc/html/draft-zyp-json-schema-04). No tiene que definir un modelo para crear una plantilla de asignación. Sin embargo, un modelo puede ayudarle a crear una plantilla porque API Gateway genera un esquema de plantilla basado en un modelo proporcionado. Para obtener más información acerca de los modelos de API Gateway, consulte [Modelos de datos para las API de REST](models-mappings-models.md).

## Expresiones de selección de plantilla
<a name="apigateway-websocket-api-template-selection-expressions"></a>

Para transformar una carga con una plantilla de mapeo, especifique una expresión de selección de plantilla de API de WebSocket en una [solicitud de integración](apigateway-websocket-api-integration-requests.md) o [respuesta de integración](apigateway-websocket-api-integration-responses.md). Esta expresión se evalúa para determinar la plantilla de entrada o de salida (si procede) que se va a utilizar para transformar ya sea el cuerpo de la solicitud en el cuerpo de la solicitud de integración (a través de una plantilla de entrada) o el cuerpo de la respuesta de integración en el cuerpo de la respuesta de ruta (a través de una plantilla de salida).

`Integration.TemplateSelectionExpression` admite `${request.body.jsonPath}` y valores estáticos.

`IntegrationResponse.TemplateSelectionExpression` admite `${request.body.jsonPath}`, `${integration.response.statuscode}`, `${integration.response.header.headerName}`, `${integration.response.multivalueheader.headerName}` y valores estáticos.

## Expresiones de selección de respuesta de integración
<a name="apigateway-websocket-api-integration-response-selection-expressions"></a>

Al [configurar una respuesta de integración](apigateway-websocket-api-integration-responses.md) para una API de WebSocket, puede especificar si lo desea una expresión de selección de respuesta de integración. Esta expresión determina qué valor de `[https://docs.aws.amazon.com/apigatewayv2/latest/api-reference/apis-apiid-integrations-integrationid-integrationresponses-integrationresponseid.html](https://docs.aws.amazon.com/apigatewayv2/latest/api-reference/apis-apiid-integrations-integrationid-integrationresponses-integrationresponseid.html)` debe seleccionarse cuando regresa una integración. El valor de esta expresión se encuentra actualmente restringido por API Gateway, tal y como se define a continuación. Tenga en cuenta que esta expresión solo se aplica a las *integraciones que no sean de proxy*; una integración de proxy simplemente transfiere la carga de respuesta de vuelta al intermediario sin realizar ningún modelado ni modificación.

A diferencia del resto de expresiones de selección precedentes, actualmente esta expresión admite un formato de *coincidencia de patrones*. La expresión debe encerrarse entre barras inclinadas.

Actualmente, el valor es fijo en función de la propiedad `[https://docs.aws.amazon.com/apigatewayv2/latest/api-reference/apis-apiid-integrations-integrationid.html#apis-apiid-integrations-integrationid-prop-integration-integrationtype](https://docs.aws.amazon.com/apigatewayv2/latest/api-reference/apis-apiid-integrations-integrationid.html#apis-apiid-integrations-integrationid-prop-integration-integrationtype)`:
+ Para integraciones basadas en Lambda, es `$integration.response.body.errorMessage`.
+ En las integraciones `HTTP` y `MOCK`, es `$integration.response.statuscode`.
+ En `HTTP_PROXY` y `AWS_PROXY`, la expresión no se utiliza, ya que se está solicitando que la carga pase hacia el intermediario.

# Configuración de asignación de datos para las API de WebSocket en API Gateway
<a name="websocket-api-data-mapping"></a>

La *asignación de datos* le permite asignar datos de una [solicitud de ruta](api-gateway-basic-concept.md#apigateway-definition-route-request) a una integración del backend.

**nota**  
El mapeo de datos para las API de WebSocket no se admite en Consola de administración de AWS. Debe utilizar la AWS CLI, AWS CloudFormation o un SDK para configurar la asignación de datos.

**Topics**
+ [Asignar datos de solicitud de ruta a parámetros de solicitud de integración](#websocket-mapping-request-parameters)
+ [Ejemplos](#websocket-data-mapping-examples)

## Asignar datos de solicitud de ruta a parámetros de solicitud de integración
<a name="websocket-mapping-request-parameters"></a>

Los parámetros de solicitud de integración se pueden asignar desde cualquier parámetro de solicitud de ruta definido, el cuerpo de la solicitud, variables [`context` o ](api-gateway-mapping-template-reference.md#context-variable-reference) [`stage`](api-gateway-mapping-template-reference.md#stagevariables-template-reference) y valores estáticos.

En la siguiente tabla se muestran las expresiones de asignación de datos de las solicitudes de integración. En la tabla, *`PARAM_NAME`* es el nombre de un parámetro de solicitud de ruta del tipo de parámetro especificado. Debe coincidir con la expresión regular `'^[a-zA-Z0-9._$-]+$]'`. *JSONPath\$1expression* es una expresión JSONPath para un campo JSON del cuerpo de la solicitud.


| Origen de datos asignado | Expresión de asignación | 
| --- | --- | 
| Cadena de consulta de solicitud (compatible solo con la ruta \$1connect) | route.request.querystring.PARAM\$1NAME | 
| Encabezado de solicitud (compatible solo con la ruta \$1connect) | route.request.header.PARAM\$1NAME | 
| Cadena de consulta de solicitud de varios valores (compatible solo con la ruta \$1connect) | route.request.multivaluequerystring.PARAM\$1NAME | 
| Encabezado de solicitud de varios valores (solo compatible con la ruta \$1connect) | route.request.multivalueheader.PARAM\$1NAME | 
| Cuerpo de la solicitud | route.request.body.JSONPath\$1EXPRESSION | 
| Variables de etapa | stageVariables.VARIABLE\$1NAME | 
| Variables de contexto | context.VARIABLE\$1NAME que debe ser alguna de las [variables de contexto admitidas](api-gateway-mapping-template-reference.md#context-variable-reference). | 
| Valor estático | 'STATIC\$1VALUE'. STATIC\$1VALUE es un literal de cadena que se debe incluir entre comillas simples. | 

Al crear una asignación de datos, mediante la AWS CLI asegúrese de seguir el formato correcto para usar literales con cadenas en la AWS CLI. Para obtener más información, consulte [Uso de entrecomillado y literales con cadenas en la AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/cli-usage-parameters-quoting-strings.html) de la *Guía del usuario de AWS Command Line Interface*.

## Ejemplos
<a name="websocket-data-mapping-examples"></a>

En los siguientes ejemplos de la AWS CLI se configuran asignaciones de datos. Para obtener una plantilla de CloudFormation, consulte [samples/websocket-data-mapping.zip](samples/websocket-data-mapping.zip).

### Asignar el connectionId de un cliente a un encabezado en una solicitud de integración
<a name="websocket-data-mapping-examples.connectionId"></a>

El siguiente comando [update-integration](https://docs.aws.amazon.com/cli/latest/reference/apigatewayv2/update-integration.html) permite asignar el `connectionId` de un cliente a un encabezado `connectionId` en la solicitud a una integración de backend:

```
aws apigatewayv2 update-integration \
    --integration-id abc123 \
    --api-id a1b2c3d4 \ 
    --request-parameters 'integration.request.header.connectionId'='context.connectionId'
```

### Asignar un parámetro de cadena de consulta a un encabezado en una solicitud de integración
<a name="websocket-data-mapping-examples.querystring"></a>

En el siguiente ejemplo, se asigna un parámetro de cadena de consulta `authToken` a un encabezado `authToken` en la solicitud de integración.

1. Utilice el siguiente comando [update-route](https://docs.aws.amazon.com/cli/latest/reference/apigatewayv2/update-route.html) para agregar el parámetro de cadena de consulta `authToken` a los parámetros de solicitud de ruta.

   ```
   aws apigatewayv2 update-route --route-id 0abcdef \
       --api-id a1b2c3d4 \
       --request-parameters '{"route.request.querystring.authToken": {"Required": false}}'
   ```

1.  Utilice el siguiente comando [update-integration](https://docs.aws.amazon.com/cli/latest/reference/apigatewayv2/update-integration.html) para asignar el parámetro de cadena de consulta al encabezado `authToken` en la solicitud a la integración de backend.

   ```
   aws apigatewayv2 update-integration \
       --integration-id abc123 \
       --api-id a1b2c3d4 \
       --request-parameters 'integration.request.header.authToken'='route.request.querystring.authToken'
   ```

1. (Opcional) Si es necesario, utilice el siguiente comando [delete-route-request-parameter](https://docs.aws.amazon.com/cli/latest/reference/apigatewayv2/delete-route-request-parameter.html) para eliminar el parámetro de cadena de consulta `authToken` de los parámetros de solicitud de ruta.

   ```
   aws apigatewayv2 delete-route-request-parameter \
       --route-id 0abcdef \
       --api-id a1b2c3d4 \
       --request-parameter-key 'route.request.querystring.authToken'
   ```

# Referencia de la plantilla de asignación de la API de WebSocket para API Gateway
<a name="apigateway-websocket-api-mapping-template-reference"></a>

En esta sección se resume el conjunto de variables compatibles actualmente con las API de WebSocket en API Gateway.


| Parámetro | Descripción | 
| --- | --- | 
| \$1context.connectionId |  Identificador único para la conexión que se puede utilizar para realizar una devolución de llamada al cliente.  | 
| \$1context.connectedAt |  Hora de la conexión en [formato de tiempo Unix](https://en.wikipedia.org/wiki/Unix_time).  | 
| \$1context.domainName |  Nombre de dominio para la API de WebSocket. Se puede utilizar para realizar una devolución de llamada al cliente (en lugar de un valor de código rígido).  | 
| \$1context.eventType |  El tipo de evento: `CONNECT`, `MESSAGE` o `DISCONNECT`.  | 
| \$1context.messageId |  Un ID único del lado del servidor para un mensaje. Solo está disponible si `$context.eventType` es `MESSAGE`.  | 
| \$1context.routeKey |  La clave de ruta seleccionada.  | 
| \$1context.requestId |  Igual que `$context.extendedRequestId`.  | 
| \$1context.extendedRequestId | Un ID generado de forma automática para la llamada a la API, que contiene más información útil para la depuración o la resolución de problemas. | 
| \$1context.apiId |  El identificador que API Gateway asigna a su API.  | 
| \$1context.authorizer.principalId |  La identificación de usuario principal asociada con el token enviado por el cliente y devuelto de una función de Lambda del autorizador de Lambda de API Gateway (que anteriormente se denominaba “autorizador personalizado”).  | 
| \$1context.authorizer.property |  El valor en forma de cadena del par clave-valor especificado de la asignación `context` que devuelve la función de Lambda del autorizador de Lambda de API Gateway. Por ejemplo, si el autorizador devuelve la siguiente asignación de `context`:  <pre>"context" : {<br />  "key": "value",<br />  "numKey": 1,<br />  "boolKey": true<br />}</pre> la llamada a `$context.authorizer.key` devuelve la cadena `"value"`, la llamada a `$context.authorizer.numKey` devuelve la cadena `"1"` y la llamada a `$context.authorizer.boolKey` devuelve la cadena `"true"`.  | 
| \$1context.error.messageString | El valor entrecomillado de \$1context.error.message, es decir, "\$1context.error.message". | 
| \$1context.error.validationErrorString |  Una cadena que contiene un mensaje de error de validación detallado.  | 
| \$1context.identity.accountId |  El ID de cuenta de AWS asociado con la solicitud.  | 
| \$1context.identity.apiKey |  Clave del propietario de API asociada a la solicitud de API habilitada para claves.  | 
| \$1context.identity.apiKeyId | ID de clave de API asociado a la solicitud de API habilitada para claves | 
| \$1context.identity.caller |  El identificador principal del intermediario que realiza la solicitud.  | 
| \$1context.identity.cognitoAuthenticationProvider |  Una lista separada por comas de todos los proveedores de autenticación de Amazon Cognito utilizados por el intermediario que realiza la solicitud. Solo está disponible si la solicitud se firmó con las credenciales de Amazon Cognito.  Por ejemplo, para una identidad de un grupo de usuarios de Amazon Cognito, `cognito-idp. region.amazonaws.com/user_pool_id,cognito-idp.region.amazonaws.com/user_pool_id:CognitoSignIn:token subject claim` Consulte [Uso de las identidades federadas](https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-identity.html) en la *Guía para desarrolladores de Amazon Cognito* para obtener información sobre los proveedores de autenticación de Amazon Cognito disponibles. | 
| \$1context.identity.cognitoAuthenticationType |  El tipo de autenticación de Amazon Cognito del intermediario que realiza la solicitud. Solo está disponible si la solicitud se firmó con las credenciales de Amazon Cognito. Los valores posibles incluyen `authenticated` para identidades autenticadas y `unauthenticated` para identidades no autenticadas. | 
| \$1context.identity.cognitoIdentityId |  El ID de identidad de Amazon Cognito del intermediario que realiza la solicitud. Solo está disponible si la solicitud se firmó con las credenciales de Amazon Cognito.  | 
| \$1context.identity.cognitoIdentityPoolId |  El ID del grupo de identidades de Amazon Cognito del intermediario que realiza la solicitud. Solo está disponible si la solicitud se firmó con las credenciales de Amazon Cognito.  | 
| \$1context.identity.sourceIp |  La dirección IP de origen de la conexión TCP inmediata que realiza la solicitud al punto de enlace de API Gateway.  | 
| \$1context.identity.user |  El identificador principal del usuario que realiza la solicitud.  | 
| \$1context.identity.userAgent |  El agente de usuario del intermediario de la API.  | 
| \$1context.identity.userArn |  El Nombre de recurso de Amazon (ARN) del usuario identificado después de la autenticación.  | 
| \$1context.requestTime | Hora de la solicitud en formato [CLF](https://httpd.apache.org/docs/current/logs.html#common)-(dd/MMM/yyyy:HH:mm:ss \$1-hhmm). | 
| \$1context.requestTimeEpoch | Hora de la solicitud en formato [Epoch](https://en.wikipedia.org/wiki/Unix_time) en milisegundos. | 
| \$1context.stage |  La etapa de implementación de la llamada a la API (por ejemplo, Beta o Prod).  | 
| \$1context.status |  Estado de la respuesta.  | 
| \$1input.body | Devuelve la carga bruta como una cadena. | 
| \$1input.json(x) | Esta función evalúa una expresión JSONPath y devuelve los resultados como una cadena JSON. Por ejemplo, `$input.json('$.pets')` devolverá una cadena JSON que representa la estructura de "pets" (mascotas). Para obtener más información acerca de JSONPath, consulte [JSONPath](https://goessner.net/articles/JsonPath/) o [JSONPath for Java](https://github.com/json-path/JsonPath). | 
| \$1input.path(x) | Toma una cadena de expresión JSONPath (`x`) y devuelve una representación del resultado en forma de objeto JSON. Esto le permite tener acceso y manipular los elementos de la carga de forma nativa en [Apache Velocity Template Language (VTL)](https://velocity.apache.org/engine/devel/vtl-reference.html). Por ejemplo, si la expresión `$input.path('$.pets')` devuelve un objeto como este: <pre>[<br />  { <br />    "id": 1, <br />    "type": "dog", <br />    "price": 249.99 <br />  }, <br />  { <br />    "id": 2, <br />    "type": "cat", <br />    "price": 124.99 <br />  }, <br />  { <br />    "id": 3, <br />    "type": "fish", <br />    "price": 0.99 <br />  } <br />]</pre> `$input.path('$.pets').count()` devolvería `"3"`. Para obtener más información acerca de JSONPath, consulte [JSONPath](http://goessner.net/articles/JsonPath/) o [JSONPath for Java](https://github.com/jayway/JsonPath). | 
| \$1stageVariables.<variable\$1name> |  *<variable\$1name>* representa un nombre de variable de etapa.  | 
| \$1stageVariables['<variable\$1name>'] |  *<variable\$1name>* representa cualquier nombre de variable de etapa.  | 
| \$1\$1stageVariables['<variable\$1name>']\$1 |  *<variable\$1name>* representa cualquier nombre de variable de etapa.  | 
| \$1util.escapeJavaScript() |  Aplica caracteres de escape a los caracteres de una cadena usando reglas de cadena de JavaScript.  Esta función convertirá todas las comillas simples (`'`) en caracteres de escape (`\'`). Sin embargo, JSON no admite comillas simples con caracteres de escape. Por lo tanto, cuando la salida de esta función se utiliza en una propiedad de JSON, debe convertir todas las comillas simples con caracteres de escape (`\'`) en comillas simples normales (`'`). Esto se muestra en el siguiente ejemplo:  <pre> $util.escapeJavaScript(data).replaceAll("\\'","'")</pre>   | 
| \$1util.parseJson() |   Toma un elemento JSON en forma de cadena y devuelve una representación del resultado en forma de objeto. Puede utilizar el resultado de esta función para tener acceso y manipular los elementos de la carga de forma nativa en Apache Velocity Template Language (VTL). Por ejemplo, si tiene la siguiente carga:  <pre>{"errorMessage":"{\"key1\":\"var1\",\"key2\":{\"arr\":[1,2,3]}}"}</pre>  y usa la siguiente plantilla de asignación  <pre>#set ($errorMessageObj = $util.parseJson($input.path('$.errorMessage')))<br />{<br />   "errorMessageObjKey2ArrVal" : $errorMessageObj.key2.arr[0]<br />}<br /></pre> Obtendrá el siguiente resultado: <pre>{<br />   "errorMessageObjKey2ArrVal" : 1<br />}<br /></pre>  | 
| \$1util.urlEncode() | Convierte una cadena en formato "application/x-www-form-urlencoded". | 
| \$1util.urlDecode() | Descodifica una cadena "application/x-www-form-urlencoded". | 
| \$1util.base64Encode() | Codifica los datos en una cadena codificada en base64. | 
| \$1util.base64Decode() | Descodifica los datos de una cadena codificada en base64. | 

# Tipos de medios binarios para las API de WebSocket en API Gateway
<a name="websocket-api-develop-binary-media-types"></a>

Actualmente, las API de WebSocket de API Gateway no admiten tramas binarias en las cargas de los mensajes entrantes. Si una aplicación cliente envía una trama binaria, API Gateway la rechaza y desconecta el cliente con el código 1003.

Existe una solución alternativa para este comportamiento. Si el cliente envía datos binarios de texto codificado (por ejemplo, base64) como una trama de texto, es posible establecer la propiedad `contentHandlingStrategy` de la integración en `CONVERT_TO_BINARY` para convertir la carga de una cadena codificada en base64 al formato binario. 

Para devolver una respuesta de ruta correspondiente a una carga binaria en las integraciones que no sean de proxy, puede establecer la propiedad `contentHandlingStrategy` de la respuesta de integración en `CONVERT_TO_TEXT` para convertir la carga del formato binario a una cadena codificada en base64.

# Invocación de las API de WebSocket
<a name="apigateway-how-to-call-websocket-api"></a>

Después de haber implementado la API de WebSocket, las aplicaciones cliente pueden conectarse a ella y mensajes destinados a ella, y el servicio de backend puede enviar mensajes a las aplicaciones cliente conectadas:
+ Puede utilizar `wscat` para conectarse a la API de WebSocket y enviar mensajes a ella para simular el comportamiento del cliente. Consulte [Utilice `wscat` para conectarse y enviar mensajes a una API de WebSocket](apigateway-how-to-call-websocket-api-wscat.md).
+ Puede utilizar la API @connections desde el servicio de backend para enviar un mensaje de devolución de llamada a un cliente conectado, obtener información sobre la conexión o desconectar el cliente. Consulte [Uso de comandos de `@connections` en el servicio de backend](apigateway-how-to-call-websocket-api-connections.md).
+ Una aplicación cliente puede utilizar su propia biblioteca de WebSocket para invocar a la API de WebSocket.

# Utilice `wscat` para conectarse y enviar mensajes a una API de WebSocket
<a name="apigateway-how-to-call-websocket-api-wscat"></a>

La utilidad `[wscat](https://www.npmjs.com/package/wscat)` es una herramienta muy práctica para probar una API de WebSocket que se ha creado e implementado en API Gateway. Puede instalar y utilizar `wscat` como se indica a continuación:

1. Descargue `wscat` de [https://www.npmjs.com/package/wscat](https://www.npmjs.com/package/wscat).

1. Instale `wscat` ejecutando el siguiente comando:

   ```
   npm install -g wscat
   ```

1. Para conectarse a su API, ejecute el comando `wscat` como se muestra en el siguiente ejemplo. Tenga en cuenta que en este ejemplo se presupone que `Authorization` es `NONE`.

   ```
   wscat -c wss://aabbccddee.execute-api.us-east-1.amazonaws.com/test/
   ```

   Tiene que sustituir `aabbccddee` por el ID real de la API, que se muestra en la consola de API Gateway o se obtiene mediante el comando [https://docs.aws.amazon.com/cli/latest/reference/apigatewayv2/create-api.html](https://docs.aws.amazon.com/cli/latest/reference/apigatewayv2/create-api.html) de la AWS CLI.

   Además, si la API está en una región distinta de `us-east-1`, tendrá que sustituirla por la región correcta.

1. Para probar la API, introduzca un mensaje como el siguiente mientras está conectado:

   ```
   {"{jsonpath-expression}":"{route-key}"}
   ```

   donde *\$1jsonpath-expression\$1* es un expresión JSONPath y *\$1route-key\$1* es una clave de ruta para la API. Por ejemplo:

   ```
   {"action":"action1"}
   {"message":"test response body"}
   ```

   Para obtener más información acerca de JSONPath, consulte [JSONPath](https://goessner.net/articles/JsonPath/) o [JSONPath for Java](https://github.com/json-path/JsonPath).

1. Para desconectarse de la API, introduzca `ctrl-C`.

# Uso de comandos de `@connections` en el servicio de backend
<a name="apigateway-how-to-call-websocket-api-connections"></a>

El servicio de backend puede utilizar las siguientes solicitudes HTTP de conexión de WebSocket para enviar un mensaje de devolución de llamada a un cliente conectado, obtener información sobre la conexión o desconectar el cliente.

**importante**  
Estas solicitudes utilizan la [autorización de IAM](apigateway-websocket-control-access-iam.md), por lo que debe firmarlas con [Signature Version 4 (SigV4)](https://docs.aws.amazon.com/IAM/latest/UserGuide/create-signed-request.html). Para hacerlo, puede usar la API de administración de API Gateway. Para obtener más información, consulte [ApiGatewayManagementApi](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/apigatewaymanagementapi.html).

En el siguiente comando, tiene que sustituir `{api-id}` por el ID real de la API, que se muestra en la consola de API Gateway o se obtiene mediante el comando [create-api](https://docs.aws.amazon.com/cli/latest/reference/apigatewayv2/create-api.html) de la AWS CLI. Debe establecer la conexión antes de utilizar este comando. 

Para enviar un mensaje de devolución de llamada al cliente, utilice:

```
POST https://{api-id}.execute-api.us-east-1.amazonaws.com/{stage}/@connections/{connection_id}
```

Puede probar esta solicitud mediante `[Postman](https://www.postman.com/)` o llamando a `[awscurl](https://github.com/okigan/awscurl)`, tal y como se muestra en el siguiente ejemplo:

```
awscurl --service execute-api -X POST -d "hello world" https://{prefix}.execute-api.us-east-1.amazonaws.com/{stage}/@connections/{connection_id}
```

Tiene que codificar el comando como URL, tal y como se muestra en el siguiente ejemplo:

```
awscurl --service execute-api -X POST -d "hello world" https://aabbccddee.execute-api.us-east-1.amazonaws.com/prod/%40connections/R0oXAdfD0kwCH6w%3D
```

Para obtener el estado de conexión más reciente del cliente, utilice:

```
GET https://{api-id}.execute-api.us-east-1.amazonaws.com/{stage}/@connections/{connection_id}
```

Para desconectar el cliente, utilice:

```
DELETE https://{api-id}.execute-api.us-east-1.amazonaws.com/{stage}/@connections/{connection_id}
```

Puede crear una URL de devolución de llamada dinámicamente mediante el uso de las variables `$context` de su integración. Por ejemplo, si utiliza la integración de proxy de Lambda con una función de Lambda `Node.js`, puede crear la URL y enviar un mensaje a un cliente conectado como se indica a continuación:

```
import {
  ApiGatewayManagementApiClient,
  PostToConnectionCommand,
} from "@aws-sdk/client-apigatewaymanagementapi";

export const handler = async (event) => {
  const domain = event.requestContext.domainName;
  const stage = event.requestContext.stage;
  const connectionId = event.requestContext.connectionId;
  const callbackUrl = `https://${domain}/${stage}`;
  const client = new ApiGatewayManagementApiClient({ endpoint: callbackUrl });

  const requestParams = {
    ConnectionId: connectionId,
    Data: "Hello!",
  };

  const command = new PostToConnectionCommand(requestParams);

  try {
    await client.send(command);
  } catch (error) {
    console.log(error);
  }

  return {
    statusCode: 200,
  };
};
```

Si utiliza un nombre de dominio personalizado para la API de WebSocket, quite la variable `stage` del código de la función.

Al enviar un mensaje de devolución de llamada, la función de Lambda debe tener permiso para llamar a la API de administración de puertas de enlace de API. Es posible que reciba un mensaje de error que contiene `GoneException` si publica un mensaje antes de que se establezca la conexión o después de que el cliente se haya desconectado. 