

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

Una API de WebSocket en API Gateway es una colección de rutas de WebSocket que se integran con puntos de enlace de HTTP del backend, funciones de Lambda u otros servicios de AWS. Puede utilizar características de API Gateway para ayudarle con todos los aspectos del ciclo de vida de la API, desde la creación hasta el monitoreo de sus API de producción.

Las API de WebSocket en API Gateway son bidireccionales. Un cliente puede enviar mensajes a un servicio y los servicios pueden enviar mensajes a los clientes de forma independiente. Este comportamiento bidireccional permite interacciones más ricas entre clientes y servicios, ya que los servicios pueden enviar datos a los clientes sin requerir que los clientes realicen una solicitud explícita. Las API de WebSocket se utilizan a menudo en aplicaciones en tiempo real como aplicaciones de chat, plataformas de colaboración, juegos multijugador y plataformas de negociación financiera.

Para ver una aplicación de ejemplo con la que empezar, consulte [Tutorial: Creación de una aplicación de chat de WebSocket con una API de WebSocket, Lambda y DynamoDB](websocket-api-chat-app.md).

En esta sección, aprenderá a desarrollar, publicar, proteger y monitorear las API de WebSocket mediante API Gateway.

**Topics**
+ [Descripción general de las API de WebSocket en API Gateway](apigateway-websocket-api-overview.md)
+ [Desarrollo de las API de WebSocket en API Gateway](websocket-api-develop.md)
+ [Publicación de las API de WebSocket para que los clientes las invoquen](websocket-api-publish.md)
+ [Protección de las API de WebSocket en API Gateway](websocket-api-protect.md)
+ [Supervisión de las API de WebSocket en API Gateway](websocket-api-monitor.md)

# Descripción general de las API de WebSocket en API Gateway
<a name="apigateway-websocket-api-overview"></a>

En API Gateway puede crear una API de WebSocket como un frontend con estado para un servicio de AWS (como Lambda o DynamoDB) o para un punto de enlace HTTP. La API de WebSocket invoca al backend en función del contenido de los mensajes que recibe de las aplicaciones cliente.

A diferencia de una API de REST, que recibe las solicitudes y responde a ellas, una API de WebSocket admite la comunicación bidireccional entre las aplicaciones cliente y el backend. El backend puede enviar mensajes de devolución de llamada a los clientes conectados.

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](websocket-api-develop-routes.md#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.

## Uso de rutas para una API de WebSocket
<a name="apigateway-websocket-api-overview-routes"></a>

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.

Para obtener más información sobre las rutas `$connect` y `$disconnect`, consulte [Administración de usuarios conectados y aplicaciones cliente: rutas `$connect` y `$disconnect`](apigateway-websocket-api-route-keys-connect-disconnect.md).

Para obtener más información sobre la ruta `$default` y las rutas personalizadas, consulte [Invocación de la integración de backend con la ruta `$default` y las rutas personalizadas en API Gateway](apigateway-websocket-api-routes-integrations.md).

## Envío de datos a las aplicaciones cliente conectadas
<a name="apigateway-websocket-api-overview-send-data"></a>

Los servicios de backend pueden enviar datos a las aplicaciones cliente conectadas. Puede enviar datos si hace lo siguiente:
+ Use una integración puede enviar una respuesta, que se devuelve al cliente mediante una respuesta de ruta que usted haya definido.
+ Puede utilizar la API `@connections` para enviar una solicitud POST. Para obtener más información, consulte [Uso de comandos de `@connections` en el servicio de backend](apigateway-how-to-call-websocket-api-connections.md).

## Códigos de estado de la API de WebSocket
<a name="apigateway-websocket-status-codes"></a>

Las API de WebSocket de API Gateway utilizan los siguientes códigos de estado para la comunicación del servidor al cliente, tal y como se describe en el [registro de números de códigos de cierre de WebSocket](https://www.iana.org/assignments/websocket/websocket.xhtml#close-code-number):

1001  
API Gateway devuelve este código de estado cuando el cliente permanece inactivo durante 10 minutos o alcanza el tiempo de conexión máximo de 2 horas.

1003  
API Gateway devuelve este código de estado cuando un punto de conexión recibe un tipo de medio binario. Los tipos de medios binarios no se admiten en las API de WebSocket.

1005  
API Gateway devuelve este código de estado si el cliente envía una trama de cierre sin un código de cierre.

1006  
API Gateway devuelve este código de estado si se produce un cierre inesperado de la conexión, como el cierre de la conexión TCP sin una trama de cierre de WebSocket.

1008  
API Gateway devuelve este código de estado cuando un punto de conexión recibe demasiadas solicitudes de un cliente concreto.

1009  
API Gateway devuelve este código de estado cuando un punto de conexión recibe un mensaje demasiado grande para procesarlo.

1011  
API Gateway devuelve este código de estado cuando se produce un error interno del servidor. 

1012  
API Gateway devuelve este código de estado si el servicio se reinicia.

# Administración de usuarios conectados y aplicaciones cliente: rutas `$connect` y `$disconnect`
<a name="apigateway-websocket-api-route-keys-connect-disconnect"></a>

En la siguiente sección se describe cómo utilizar las rutas `$connect` y `$disconnect` para la API de WebSocket.

**Topics**
+ [La ruta `$connect`](#apigateway-websocket-api-routes-about-connect)
+ [Transmitir información de conexión de la ruta `$connect`](#apigateway-websocket-api-passing-connectionId-on-connect)
+ [La ruta `$disconnect`](#apigateway-websocket-api-routes-about-disconnect)

## La ruta `$connect`
<a name="apigateway-websocket-api-routes-about-connect"></a>

Las aplicaciones cliente se conectan a la API de WebSocket enviando una solicitud de actualización de WebSocket. Si la solicitud se realiza correctamente, la ruta `$connect` se ejecuta mientras se establece la conexión.

Dado que la conexión de WebSocket es una conexión con estado, solo se puede configurar la autorización en la ruta `$connect`. `AuthN`/`AuthZ` solo se realizará en el momento de la conexión.

Hasta que se complete la ejecución de la integración asociada a la ruta `$connect`, la solicitud de actualización está pendiente y la conexión real no se establece. Si la solicitud `$connect` da error (por ejemplo, debido a un error de `AuthN`/`AuthZ` o de integración), la conexión no se realizará.

**nota**  
Si se produce un error en la autorización en `$connect`, la conexión no se establece y el cliente recibirá una respuesta `401` o `403`.

La configuración de una integración para `$connect` es opcional. Considere la posibilidad de configurar una integración `$connect` si:
+ Desea habilitar a los clientes para especificar subprotocolos mediante el campo `Sec-WebSocket-Protocol`. Para ver código de ejemplo, consulte [Configuración de una ruta `$connect` que requiere un subprotocolo WebSocket](websocket-connect-route-subprotocol.md).
+ Desea recibir una notificación cuando los clientes se conectan.
+ Desea limitar las conexiones o controlar quién se conecta.
+ Desea que el backend envíe mensajes de respuesta a los clientes mediante una URL de devolución de llamada.
+ Desea almacenar los ID de conexión y otra información en una base de datos (por ejemplo, Amazon DynamoDB).

## Transmitir información de conexión de la ruta `$connect`
<a name="apigateway-websocket-api-passing-connectionId-on-connect"></a>

 Puede utilizar integraciones con y sin proxy para transferir información de la ruta `$connect` a una base de datos u otro Servicio de AWS. 

### Para transferir información de conexión mediante una integración de proxy
<a name="websocket-connect-proxy-integration"></a>

En ese caso, puede acceder a la información de conexión desde una integración de proxy de Lambda. Utilice otro Servicio de AWS o función de AWS Lambda para publicar en la conexión. 

La siguiente función de Lambda muestra cómo utilizar el objeto `requestContext` para registrar el ID de conexión, el nombre de dominio, el nombre de etapa y las cadenas de consulta. 

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

```
 export const handler = async(event, context) => {
    const connectId = event["requestContext"]["connectionId"]
    const domainName = event["requestContext"]["domainName"]
    const stageName = event["requestContext"]["stage"]
    const qs = event['queryStringParameters']
    console.log('Connection ID: ', connectId, 'Domain Name: ', domainName, 'Stage Name: ', stageName, 'Query Strings: ', qs )
    return {"statusCode" : 200}
};
```

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

```
import json
import logging
logger = logging.getLogger()
logger.setLevel("INFO")


def lambda_handler(event, context):
    connectId = event["requestContext"]["connectionId"]
    domainName = event["requestContext"]["domainName"]
    stageName = event["requestContext"]["stage"]
    qs = event['queryStringParameters']
    connectionInfo = {
        'Connection ID': connectId,
        'Domain Name': domainName,
        'Stage Name': stageName,
        'Query Strings': qs}
    logging.info(connectionInfo)
    return {"statusCode": 200}
```

------

### Para transferir información de conexión mediante una integración que no sea de proxy
<a name="websocket-connect-non-proxy-integration"></a>
+ Puede acceder a la información de conexión con una integración que no sea de proxy. Configure la solicitud de integración y proporcione una plantilla de solicitud de API de WebSocket. La siguiente plantilla de mapeo [Velocity Template Language (VTL)](https://velocity.apache.org/engine/devel/vtl-reference.html) proporciona una solicitud de integración. Esta solicitud envía los siguientes detalles a una integración que no sea de proxy: 
  + ID de la conexión
  + Nombre del dominio
  + Nombre de la fase
  + Ruta
  + Encabezados
  + Cadenas de consulta

  Esta solicitud envía el ID de conexión, el nombre de dominio, el nombre de etapa, las rutas, los encabezados y las cadenas de consulta a una integración que no sea de proxy.

  ```
  {
      "connectionId": "$context.connectionId",
      "domain": "$context.domainName",
      "stage": "$context.stage",
      "params": "$input.params()"
  }
  ```

  Para obtener más información sobre la configuración de transformaciones de datos, consulte [Transformaciones de datos para las API de WebSocket en API Gateway](websocket-api-data-transformations.md).

  Para completar la solicitud de integración, establezca `StatusCode: 200` para la respuesta de integración. Para obtener más información sobre la configuración de una respuesta de integración, consulte [Configuración de una respuesta de integración mediante la consola de API Gateway](apigateway-websocket-api-integration-responses.md#apigateway-websocket-api-integration-response-using-console).

## La ruta `$disconnect`
<a name="apigateway-websocket-api-routes-about-disconnect"></a>

La ruta `$disconnect` se ejecuta una vez que se ha cerrado la conexión.

La conexión la puede cerrar el servidor o el cliente. Como la conexión ya está cerrada cuando se ejecuta, `$disconnect` es un evento de mejor esfuerzo. API Gateway hará todo lo posible para entregar el evento `$disconnect` a su integración, pero no puede garantizar la entrega.

El backend puede iniciar la desconexión mediante la API `@connections`. Para obtener más información, consulte [Uso de comandos de `@connections` en el servicio de backend](apigateway-how-to-call-websocket-api-connections.md).

# Invocación de la integración de backend con la ruta `$default` y las rutas personalizadas en API Gateway
<a name="apigateway-websocket-api-routes-integrations"></a>

En la siguiente sección se describe cómo invocar su integración de backend mediante la ruta `$default` o una ruta personalizada para una API de WebSocket.

**Topics**
+ [Uso de rutas para procesar mensajes](#apigateway-websocket-api-overview-routes)
+ [La ruta `$default`](#apigateway-websocket-api-routes-about-default)
+ [Rutas personalizadas](#apigateway-websocket-api-routes-about-custom)
+ [Uso de las integraciones de API de WebSocket de API Gateway para conectarse a la lógica de negocio](#apigateway-websocket-api-overview-integrations)
+ [Diferencias importantes entre las API de WebSocket y las API de REST](#apigateway-websocket-api-overview-integrations-differences)

## Uso de rutas para procesar mensajes
<a name="apigateway-websocket-api-overview-routes"></a>

En las API de WebSocket de API Gateway, es posible enviar mensajes desde el cliente al servicio de backend y viceversa. A diferencia del modelo solicitud/respuesta de HTTP, en WebSocket el backend puede enviar mensajes al cliente sin que este realice ninguna acción.

Los mensajes pueden ser tener el formato JSON u otro distinto. Sin embargo, solo los mensajes JSON se pueden direccionar a integraciones específicas en función del contenido del mensaje. Los mensajes que no tienen el formato JSON se transmiten a través del backend por la ruta `$default`.

**nota**  
API Gateway admite cargas de mensajes de hasta 128 KB con un tamaño máximo de trama de 32 KB. Si un mensaje supera los 32 KB, se debe dividir en varias tramas, cada una con tamaño máximo de 32 KB. Si se recibe un mensaje (o una trama) más grande, la conexión se cierra con el código 1009.  
Actualmente, no se admiten cargas binarias. Si se recibe una trama binaria, la conexión se cierra con el código 1003. Sin embargo, es posible convertir cargas binarias a texto. Consulte [Tipos de medios binarios para las API de WebSocket en API Gateway](websocket-api-develop-binary-media-types.md).

Con las API de WebSocket en API Gateway, los mensajes JSON se pueden direccionar para ejecutar un servicio de backend específico en función del contenido del mensaje. Cuando un cliente envía un mensaje a través de su conexión WebSocket, esto da lugar a una *solicitud de ruta* a la API de WebSocket. La solicitud se emparejará con la ruta que tenga la clave de ruta correspondiente en API Gateway. Puede configurar una solicitud de ruta para una API de WebSocket en la consola de API Gateway, mediante la AWS CLI o mediante un AWS SDK.

**nota**  
Tanto la AWS CLI como los SDK de AWS le permiten crear rutas antes o después de generar las integraciones. Actualmente, la consola no admite la reutilización de integraciones, por lo que debe crear primero la ruta y, a continuación, la integración de dicha ruta.

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 no se supera la validación, API Gateway rechaza la solicitud sin llamar al backend, envía una respuesta de gateway `"Bad request body"` similar a la siguiente al cliente y publica los resultados de la validación en CloudWatch Logs: 

```
{"message" : "Bad request body", "connectionId": "{connectionId}", "messageId": "{messageId}"}
```

Esto reduce las llamadas innecesarias al backend y le permite centrarse en los demás requisitos de la API.

También puede definir una respuesta de ruta para las rutas de la API con objeto de permitir la comunicación bidireccional. Una respuesta de ruta describe qué datos se enviarán al cliente al finalizar la integración de una ruta determinada. No es necesario definir una respuesta para una ruta si, por ejemplo, desea que un cliente envíe mensajes al backend sin recibir una respuesta (comunicación unidireccional). Sin embargo, si no se proporciona una respuesta de ruta, API Gateway no enviará ninguna información sobre el resultado de la integración a los clientes.

## La ruta `$default`
<a name="apigateway-websocket-api-routes-about-default"></a>

Cada API de WebSocket de API Gateway puede tener una ruta `$default`. Se trata de un valor de direccionamiento especial que se puede utilizar de las siguientes formas:
+ Puede utilizarlo junto con claves de ruta definidas para especificar una ruta "alternativa" (por ejemplo, una integración simulada genérica que devuelve un mensaje de error determinado) para los mensajes entrantes que no coinciden con ninguna de las claves de ruta definidas.
+ Puede utilizarlo sin claves de ruta definidas para especificar un modelo de proxy que delega el direccionamiento en un componente del backend.
+ También puede usarlo si desea especificar una ruta para las cargas que no son JSON.

## Rutas personalizadas
<a name="apigateway-websocket-api-routes-about-custom"></a>

Si desea invocar una integración específica en función del contenido del mensaje, puede hacerlo mediante la creación de una ruta personalizada.

Una ruta personalizada utiliza la clave de ruta y la integración que se especifiquen. Si un mensaje entrante contiene una propiedad JSON y dicha propiedad toma un valor que coincide con el valor de la clave de ruta, API Gateway invoca la integración. (Para obtener más información, consulte [Descripción general de las API de WebSocket en API Gateway](apigateway-websocket-api-overview.md).)

Por ejemplo, supongamos que desea crear una aplicación de sala de chat. Puede comenzar creando una API de WebSocket cuya expresión de selección de ruta sea `$request.body.action`. A continuación, puede definir dos rutas: `joinroom` y `sendmessage`. Una aplicación cliente podría invocar la ruta `joinroom` enviando un mensaje como el siguiente:

```
{"action":"joinroom","roomname":"developers"}
```

También podría invocar la ruta `sendmessage` enviando un mensaje como el siguiente:

```
{"action":"sendmessage","message":"Hello everyone"}
```

## Uso de las integraciones de API de WebSocket de API Gateway para conectarse a la lógica de negocio
<a name="apigateway-websocket-api-overview-integrations"></a>

Después de configurar una ruta para una API de WebSocket de API Gateway, debe especificar la integración que desea utilizar. Al igual que ocurre con las rutas, que pueden tener una solicitud de ruta y una respuesta de ruta, las integraciones pueden tener una *solicitud de integración* y una *respuesta de integración*. Una *solicitud de integración* contiene la información que espera el backend para poder procesar la solicitud procedente del cliente. Una *respuesta de integración* contiene los datos que el backend devuelve a API Gateway y que se pueden utilizar para construir un mensaje que se envía al cliente (si se ha definido una respuesta de ruta).

Para obtener más información sobre la configuración de integraciones, consulte [Integraciones de API de WebSocket en API Gateway](apigateway-websocket-api-integrations.md).

## Diferencias importantes entre las API de WebSocket y las API de REST
<a name="apigateway-websocket-api-overview-integrations-differences"></a>

Las integraciones para las API de WebSocket son similares a las integraciones para las API de REST, con las siguientes salvedades:
+ Actualmente, se debe crear primero una ruta en la consola de API Gateway y, a continuación, crear una integración como destino de dicha ruta. Sin embargo, en la API y la CLI, es posible crear rutas e integraciones de forma independiente, en cualquier orden.
+ Puede utilizar una única integración para varias rutas. Por ejemplo, si dispone de un conjunto de acciones estrechamente relacionadas entre sí, podría ser conveniente que todas estas rutas vayan a una única función de Lambda. En lugar de definir los detalles de la integración varias veces, puede especificarla una vez y asignarla a cada una de las rutas relacionadas.
**nota**  
Actualmente, la consola no admite la reutilización de integraciones, por lo que debe crear primero la ruta y, a continuación, la integración de dicha ruta.  
En la AWS CLI y los SDK de AWS, se puede reutilizar una integración estableciendo el destino de la ruta en el valor `"integrations/{integration-id}"`, donde `{integration-id}"` es el ID exclusivo de la integración que se va a asociar a la ruta.
+ API Gateway ofrece varias [expresiones de selección](apigateway-websocket-api-selection-expressions.md) que se pueden utilizar en las rutas e integraciones. La selección de una plantilla de entrada o una asignación de salida no depende del tipo de contenido. Al igual que ocurre con las expresiones de selección de ruta, puede definir una expresión de selección que API Gateway evaluará para elegir el elemento correcto. Todas ellas recurrirán a la plantilla `$default` si no se encuentra una plantilla coincidente.
  + En las solicitudes de integración, la expresión de selección de plantillas admite `$request.body.<json_path_expression>` y valores estáticos.
  + En las respuestas de integración, la expresión de selección de plantillas admite `$request.body.<json_path_expression>`, `$integration.response.statuscode` y `$integration.response.header.<headerName>`, además de valores estáticos.

En el protocolo HTTP, en el que se envían solicitudes y respuestas de forma síncrona, la comunicación es básicamente unidireccional. En el protocolo WebSocket, la comunicación es bidireccional. Las respuestas son asíncronas y el cliente no las recibe necesariamente en el mismo orden en el que se enviaron sus mensajes. Además, el backend puede enviar mensajes al cliente.

**nota**  
En una ruta que se ha configurado para utilizar la integración `AWS_PROXY` o `LAMBDA_PROXY`, la comunicación es unidireccional y API Gateway no pasará la respuesta del backend a la respuesta de ruta de forma automática. Por ejemplo, en el caso de la integración `LAMBDA_PROXY`, el cuerpo que devuelve la función de Lambda no se enviará al cliente. Si desea que el cliente reciba respuestas de integración, debe definir una respuesta de ruta para posibilitar la comunicación bidireccional.

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

API Gateway utiliza expresiones de selección como forma de evaluar el contexto de solicitud y respuesta y producir una clave. La clave se utiliza para seleccionar un valor de un conjunto de valores posibles, normalmente proporcionados por el desarrollador de la API. El conjunto exacto de variables admitidas variará en función de la expresión dada. A continuación se describe con más detalle cada expresión.

En todas las expresiones, el lenguaje sigue el mismo conjunto de reglas:
+ Las variables tienen el prefijo `"$"`.
+ Se pueden utilizar llaves para definir explícitamente los límites de las variables, por ejempl., `"${request.body.version}-beta"`.
+ Se admite el uso de varias variables, pero la evaluación solo se produce una vez (sin evaluación recursiva).
+ A los signos de dólar (`$`) se les puede aplicar una secuencia de escape con `"\"`. Esto resulta muy útil al definir una expresión que se asigna a la clave `$default` reservada, como, por ejemplo, `"\$default"`.
+ En algunos casos, se requiere un patrón de formato. En este caso, la expresión debe encerrarse entre barras inclinadas (`"/"`), por ejemplo `"/2\d\d/"`, para que coincida con los códigos de estado `2XX`.

**Topics**
+ [Expresiones de selección de respuesta de ruta](#apigateway-websocket-api-route-response-selection-expressions)
+ [Expresiones de selección de clave de API](#apigateway-websocket-api-apikey-selection-expressions)
+ [Expresiones de selección de asignación de API](#apigateway-websocket-api-mapping-selection-expressions)
+ [Resumen de expresiones de selección de WebSocket](#apigateway-websocket-api-selection-expression-table)

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

Las [respuestas de ruta](apigateway-websocket-api-route-response.md) se utilizan para modelar una respuesta desde el backend al cliente. En la API de WebSocket, la respuesta de ruta es opcional. Si se define, indica a API Gateway que debe devolver una respuesta a un cliente al recibir un mensaje de WebSocket.

La evaluación de la *expresión de selección de respuesta de ruta* produce una clave de respuesta de ruta. Con el tiempo, esta clave se utilizará para elegir una de las respuestas [https://docs.aws.amazon.com/apigatewayv2/latest/api-reference/apis-apiid-routes-routeid-routeresponses.html](https://docs.aws.amazon.com/apigatewayv2/latest/api-reference/apis-apiid-routes-routeid-routeresponses.html) asociadas a la API. Sin embargo, actualmente solo se admite la clave `$default`.

## Expresiones de selección de clave de API
<a name="apigateway-websocket-api-apikey-selection-expressions"></a>

Esta expresión se evalúa cuando el servicio determina que la solicitud dada debe continuar solo si el cliente proporciona una [clave de API](api-gateway-basic-concept.md#apigateway-definition-api-key) válida.

Actualmente, los únicos dos valores admitidos son `$request.header.x-api-key` y `$context.authorizer.usageIdentifierKey`.

## Expresiones de selección de asignación de API
<a name="apigateway-websocket-api-mapping-selection-expressions"></a>

Esta expresión se evalúa para determinar qué etapa de API está seleccionada cuando se realiza una solicitud mediante un dominio personalizado.

Actualmente el único valor admitido es `$request.basepath`.

## Resumen de expresiones de selección de WebSocket
<a name="apigateway-websocket-api-selection-expression-table"></a>

En la tabla siguiente, se resumen los casos de uso de las expresiones de selección en las API de WebSocket:


| Expresión de selección | Se evalúa como la clave para | Notas | Ejemplo de caso de uso | 
| --- | --- | --- | --- | 
| Api.RouteSelectionExpression | Route.RouteKey | \$1default se admite como una ruta catch-all. | Direccionar los mensajes de WebSocket en función del contexto de una solicitud de cliente. | 
| Route.ModelSelectionExpression | Clave para Route.RequestModels | Opcional. Si se proporciona para una integración que no sea de proxy, se produce la validación del modelo. `$default` se admite como método catch-all.  | Realizar la validación de solicitudes de forma dinámica dentro de la misma ruta. | 
| Integration.TemplateSelectionExpression | Clave para Integration.RequestTemplates |  Opcional. Se puede proporcionar para la integración que no sea de proxy con el fin de manipular las cargas entrantes. `${request.body.jsonPath}`Se admiten y valores estáticos. `$default` se admite como método catch-all.  | Manipular la solicitud del intermediario en función de las propiedades dinámicas de la solicitud. | 
| Integration.IntegrationResponseSelectionExpression | IntegrationResponse.IntegrationResponseKey |  Opcional. Se puede proporcionar para una integración que no sea de proxy. Actúa como una coincidencia de patrones para los mensajes de error (de Lambda) o los códigos de estado (de las integraciones HTTP). `$default` es necesario en las integraciones que no sean de proxy para que actúe como el método catch-all para las respuestas correctas.  |  Manipular la respuesta del backend. Elegir la acción que debe realizarse en función de la respuesta dinámica del backend (por ejemplo, controlar de forma inequívoca determinados errores).  | 
| IntegrationResponse.TemplateSelectionExpression | Clave para IntegrationResponse.ResponseTemplates | Opcional. Se puede proporcionar para una integración que no sea de proxy. Se admite \$1default.  |  En algunos casos, una propiedad dinámica de la respuesta puede dictar la necesidad de transformaciones diferentes dentro de la misma ruta y la integración asociada. `${request.body.jsonPath}`, `${integration.response.statuscode}`, `${integration.response.header.headerName}`, `${integration.response.multivalueheader.headerName}`, Se admiten , , , y valores estáticos. `$default` se admite como método catch-all.  | 
| Route.RouteResponseSelectionExpression | RouteResponse.RouteResponseKey |  Debe proporcionarse para iniciar la comunicación bidireccional en una ruta de WebSocket. Actualmente, este valor está restringido únicamente a `$default`.  |  | 
| RouteResponse.ModelSelectionExpression | Clave para RouteResponse.RequestModels | No se admite actualmente. |  | 

# 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. 

# Publicación de las API de WebSocket para que los clientes las invoquen
<a name="websocket-api-publish"></a>

El hecho de crear y desarrollar simplemente una API de API Gateway no hace que automáticamente los usuarios puedan invocarla. Para que sea invocable, debe implementar su API en una etapa. Además, es posible que desee personalizar la URL que utilizarán los usuarios para acceder a su API. Puedes darle un dominio que sea coherente con su marca o que sea más memorable que la URL predeterminada de su API.

En esta sección, puede aprender a implementar su API y personalizar la URL que proporciona a los usuarios para acceder a ella. 

**nota**  
Para aumentar la seguridad de las API de API Gateway, el dominio `execute-api.{region}.amazonaws.com` se registra en la [lista de sufijos públicos (PSL)](https://publicsuffix.org/). Para mayor seguridad, recomendamos que utilice cookies con un prefijo `__Host-` en caso de que necesite configurar cookies confidenciales en el nombre de dominio predeterminado de las API de API Gateway. Esta práctica le ayudará a proteger su dominio de los intentos de falsificación de solicitudes entre sitios (CSRF). Para obtener más información, consulte la página de [configuración de cookies](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie#cookie_prefixes) en la red de desarrolladores de Mozilla.

**Topics**
+ [Creación de etapas para las API de WebSocket en API Gateway](websocket-api-stages.md)
+ [Implementación de las API de WebSocket en API Gateway](apigateway-set-up-websocket-deployment.md)
+ [Política de seguridad de las API de WebSocket en API Gateway](websocket-api-ciphers.md)
+ [Nombres de dominio personalizados para las API de WebSocket en API Gateway](websocket-api-custom-domain-names.md)

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

Una referencia lógica a un estado del ciclo de vida de la API (por ejemplo, `dev`, `prod`, `beta` o `v2`). Las etapas de API se identifican por su ID de API y su nombre de etapa, y se incluyen en la URL que utiliza para invocar la API. Cada etapa es una referencia con nombre a una implementación de la API y está disponible para que las aplicaciones cliente la invoquen.

Una implementación es una instantánea de la configuración de la API. Después de implementar una API en una etapa, esta está disponible para que los clientes la invoquen. Debe implementar una API para que los cambios surtan efecto.

## Variables de etapa
<a name="websocket-api-stages.stage-variables"></a>

Las variables de etapa son pares clave-valor que se pueden definir para una etapa de una API WebSocket. Actúan como variables de entorno y se pueden usar en la configuración de la API.

Por ejemplo, puede definir una variable de etapa y, a continuación, establecer su valor como extremo HTTP para una integración de proxy HTTP. Posteriormente, puede hacer referencia al punto de conexión mediante el nombre de variable de etapa asociada. Al hacer esto, puede usar la misma configuración de API con un punto de conexión diferente en cada etapa. Del mismo modo, puede utilizar variables de etapa para especificar una integración de funciones de AWS Lambda diferente para cada etapa de su API.

**nota**  
Las variables de etapa no están pensadas a fin de ser utilizadas para datos confidenciales, como credenciales. Para transferir información confidencial a las integraciones, utilice un autorizador de AWS Lambda. Puede pasar datos confidenciales a integraciones en la salida del autorizador de Lambda. Para obtener más información, consulte [Formato de respuesta del autorizador de Lambda](http-api-lambda-authorizer.md#http-api-lambda-authorizer.payload-format-response).

### Ejemplos
<a name="websocket-api-stages.stage-variables-examples"></a>

Para utilizar una variable de etapa para personalizar el punto de conexión de integración HTTP, primero debe establecer el nombre y el valor de la variable de etapa (por ejemplo, `url`) con un valor de `example.com`. A continuación, configure una integración de proxy HTTP. En lugar de escribir la URL del punto de conexión, puede indicar a API Gateway que use el valor de la variable de etapa, **http://\$1\$1stageVariables.url\$1**. Este valor indica a API Gateway que sustituya la variable de etapa `${}` en el tiempo de ejecución en función de la etapa de la API. 

Puede hacer referencia a variables de etapa de una manera similar para especificar el nombre de una función de Lambda o el ARN de un rol de AWS.

Cuando especifica el nombre de una función de Lambda como un valor de variable de etapa, debe configurar manualmente los permisos en la función de Lambda. El siguiente comando [add-permission](https://docs.aws.amazon.com/cli/latest/reference/lambda/add-permission.html) permite agregar los permisos necesarios:

```
aws lambda add-permission --function-name arn:aws:lambda:XXXXXX:your-lambda-function-name --source-arn arn:aws:execute-api:us-east-1:YOUR_ACCOUNT_ID:api_id/*/HTTP_METHOD/resource --principal apigateway.amazonaws.com --statement-id apigateway-access --action lambda:InvokeFunction
```

## Referencia de variables de etapa de API Gateway
<a name="websocket-api-stages.stage-variables-reference"></a>

### URI de integración HTTP
<a name="websocket-api-stages.stage-variables-in-integration-HTTP-uris"></a>

Puede utilizar una variable de etapa como parte de una URI de integración HTTP, tal y como se muestra en los siguientes ejemplos.
+ Una URI completa sin protocol – `http://${stageVariables.<variable_name>}`
+ Un dominio complet – `http://${stageVariables.<variable_name>}/resource/operation`
+ Un subdomini – `http://${stageVariables.<variable_name>}.example.com/resource/operation`
+ Una rut – `http://example.com/${stageVariables.<variable_name>}/bar`
+ Una cadena de consult – `http://example.com/foo?q=${stageVariables.<variable_name>}` 

### Funciones de Lambda
<a name="websocket-api-stages.stage-variables-in-integration-lambda-functions"></a>

 Puede utilizar una variable de etapa en lugar de un nombre de función de Lambda o alias, como se muestra en los ejemplos siguientes. 
+ `arn:aws:apigateway:<region>:lambda:path/2015-03-31/functions/arn:aws:lambda:<region>:<account_id>:function:${stageVariables.<function_variable_name>}/invocations`
+ `arn:aws:apigateway:<region>:lambda:path/2015-03-31/functions/arn:aws:lambda:<region>:<account_id>:function:<function_name>:${stageVariables.<version_variable_name>}/invocations`

**nota**  
Para utilizar una variable de etapa para una función de Lambda, la función debe estar en la misma cuenta que la API. Las variables de etapa no admiten funciones de Lambda entre cuentas.

### AWSCredenciales de integración de
<a name="websocket-api-stages.stage-variables-in-integration-aws-credentials"></a>

 Puede utilizar una variable de etapa como parte de un ARN de credenciales de usuario o rol de AWS, como se muestra en el siguiente ejemplo. 
+  `arn:aws:iam::<account_id>:${stageVariables.<variable_name>}` 

# Implementación de las API de WebSocket en API Gateway
<a name="apigateway-set-up-websocket-deployment"></a>

 Después de crear la API de WebSocket, debe implementarla para que los usuarios puedan invocarla. 

Para implementar una API, debe crear una [implementación de API](api-gateway-basic-concept.md#apigateway-definition-api-deployment) y asociarla con una [etapa](api-gateway-basic-concept.md#apigateway-definition-api-stage). Cada etapa es una instantánea de la API que está disponible para que las aplicaciones cliente la invoquen. 

**importante**  
Cada vez que actualice una API, debe volver a implementarla. Los cambios que no sean en la configuración del escenario requieren una nueva implementación, incluidas las modificaciones en los siguientes recursos:  
Rutas
Integraciones
Autorizadores
De forma predeterminada, se puede incluir un máximo de 10 etapas por cada API. Se recomienda reutilizar las etapas para las implementaciones. 

Para llamar a una API de WebSocket implementada, el cliente envía un mensaje a la URL de la API. La URL está determinada por el nombre de host y el nombre de etapa de la API.

**nota**  
API Gateway admitirá cargas de hasta 128 KB con un tamaño máximo de trama de 32 KB. Si un mensaje supera los 32 KB, se debe dividir en varias tramas, cada una con un tamaño máximo de 32 KB.

Por ejemplo, si se utiliza el nombre de dominio predeterminado de la API, la URL de una API de WebSocket en una determinada etapa (`{stageName}`) tendrá el siguiente formato:

```
wss://{api-id}.execute-api.{region}.amazonaws.com/{stageName}
```

Para simplificar la URL de la API de WebSocket, puede crear un nombre de dominio personalizado (por ejemplo, `api.example.com`) para sustituir el nombre de host predeterminado de la API. El proceso de configuración es el mismo que para las API de REST. Para obtener más información, consulte [Nombre de dominio personalizado para las API de REST públicas en API Gateway](how-to-custom-domains.md).

Las etapas permiten realizar un exhaustivo control de versiones de la API. Por ejemplo, puede implementar una API en una etapa `test` y una etapa `prod`, y utilizar la etapa `test` como compilación de pruebas y la etapa `prod` como compilación estable. Una vez que las actualizaciones superan la prueba, puede promover la etapa `test` como etapa `prod`. La promoción puede hacerse implementando de nuevo la API en la etapa `prod`. Para obtener más información sobre las etapas, consulte [Configuración de una etapa para una API de REST en API Gateway](set-up-stages.md).

**Topics**
+ [Creación de una implementación de la API de WebSocket mediante la AWS CLI](#apigateway-create-websocket-deployment-using-awscli)
+ [Creación de una implementación de la API de WebSocket mediante la consola de API Gateway](#apigateway-create-websocket-deployment-using-console)

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

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

```
aws apigatewayv2 --region us-east-1 create-deployment --api-id aabbccddee
```

El resultado será similar al siguiente:

```
{
    "DeploymentId": "fedcba",
    "DeploymentStatus": "DEPLOYED",
    "CreatedDate": "2018-11-15T06:49:09Z"
}
```

La API implementada no se puede invocar hasta que la implementación se asocia a una etapa. Puede crear una etapa nueva o reutilizar una creada previamente.

El siguiente comando [create-stage](https://docs.aws.amazon.com/cli/latest/reference/apigatewayv2/create-stage.html) permite crear una nueva etapa y asociarla a la implementación:

```
aws apigatewayv2 --region us-east-1 create-stage --api-id aabbccddee --deployment-id fedcba --stage-name test
```

El resultado es similar al siguiente:

```
{
    "StageName": "test",
    "CreatedDate": "2018-11-15T06:50:28Z",
    "DeploymentId": "fedcba",
    "DefaultRouteSettings": {
        "MetricsEnabled": false,
        "ThrottlingBurstLimit": 5000,
        "DataTraceEnabled": false,
        "ThrottlingRateLimit": 10000.0
    },
    "LastUpdatedDate": "2018-11-15T06:50:28Z",
    "StageVariables": {},
    "RouteSettings": {}
}
```

También puede reutilizar una etapa ya existente actualizando la propiedad `deploymentId` de la etapa con el ID de la implementación que acaba de crear (*deployment-id*). El siguiente comando [update-stage](https://docs.aws.amazon.com/cli/latest/reference/apigatewayv2/update-stage.html) permite actualizar el ID de implementación de la etapa:

```
aws apigatewayv2 update-stage --region region \
    --api-id api-id \ 
    --stage-name stage-name \ 
    --deployment-id deployment-id
```

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

Para utilizar la consola de API Gateway para crear una implementación de una API de WebSocket:

1. Inicie sesión en la consola de API Gateway y elija la API.

1. Elija **Implementar API**.

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

# Política de seguridad de las API de WebSocket en API Gateway
<a name="websocket-api-ciphers"></a>

API Gateway aplica una política de seguridad de `TLS_1_2` para todos los puntos de conexión de la API de WebSocket.

Una *política de seguridad* es una combinación predefinida de versión mínima de TLS y conjuntos de cifrado que ofrece Amazon API Gateway. El protocolo TLS soluciona los problemas de seguridad de red como, por ejemplo, la manipulación y el acceso no autorizado entre un cliente y el servidor. Cuando sus clientes establecen un protocolo de conexión a TLS con la API a través del dominio personalizado, la política de seguridad aplica la versión de TLS y opciones del conjunto de cifrado que sus clientes pueden elegir utilizar. Esta política de seguridad acepta el tráfico de TLS 1.2 y TLS 1.3 y rechaza el tráfico de TLS 1.0.

## Protocolos y cifrados TLS compatibles para las API de WebSocket
<a name="websocket-api-custom-domain-ciphers-list"></a>

En la siguiente tabla se describen los protocolos TLS compatibles con las API de WebSocket.


| **Protocolos TLS** | **Política de seguridad de TLS\$11\$12** | 
| --- | --- | 
| TLSv1.3 | ![\[alt text not found\]](http://docs.aws.amazon.com/es_es/apigateway/latest/developerguide/images/success_icon.svg) Sí | 
| TLSv1.2 | ![\[alt text not found\]](http://docs.aws.amazon.com/es_es/apigateway/latest/developerguide/images/success_icon.svg) Sí | 

En la siguiente tabla se describen los cifrados de TLS que están disponibles para la política de seguridad de TLS 1\$12 para las API de WebSocket.


| **Cifrados TLS** | **Política de seguridad de TLS\$11\$12** | 
| --- | --- | 
| TLS\$1AES\$1128\$1GCM\$1SHA256 | ![\[alt text not found\]](http://docs.aws.amazon.com/es_es/apigateway/latest/developerguide/images/success_icon.svg) Sí | 
| TLS\$1AES\$1256\$1GCM\$1SHA384 | ![\[alt text not found\]](http://docs.aws.amazon.com/es_es/apigateway/latest/developerguide/images/success_icon.svg) Sí | 
| TLS\$1CHACHA20\$1POLY1305\$1SHA256 | ![\[alt text not found\]](http://docs.aws.amazon.com/es_es/apigateway/latest/developerguide/images/success_icon.svg) Sí | 
| ECDHE-ECDSA-AES128-GCM-SHA256 | ![\[alt text not found\]](http://docs.aws.amazon.com/es_es/apigateway/latest/developerguide/images/success_icon.svg) Sí | 
| ECDHE-RSA-AES128-GCM-SHA256 | ![\[alt text not found\]](http://docs.aws.amazon.com/es_es/apigateway/latest/developerguide/images/success_icon.svg) Sí | 
| ECDHE-ECDSA-AES128-SHA256 | ![\[alt text not found\]](http://docs.aws.amazon.com/es_es/apigateway/latest/developerguide/images/success_icon.svg) Sí | 
| ECDHE-RSA-AES128-SHA256 | ![\[alt text not found\]](http://docs.aws.amazon.com/es_es/apigateway/latest/developerguide/images/success_icon.svg) Sí | 
| ECDHE-ECDSA-AES256-GCM-SHA384 | ![\[alt text not found\]](http://docs.aws.amazon.com/es_es/apigateway/latest/developerguide/images/success_icon.svg) Sí | 
| ECDHE-RSA-AES256-GCM-SHA384 | ![\[alt text not found\]](http://docs.aws.amazon.com/es_es/apigateway/latest/developerguide/images/success_icon.svg) Sí | 
| ECDHE-ECDSA-AES256-SHA384 | ![\[alt text not found\]](http://docs.aws.amazon.com/es_es/apigateway/latest/developerguide/images/success_icon.svg) Sí | 
| ECDHE-RSA-AES256-SHA384 | ![\[alt text not found\]](http://docs.aws.amazon.com/es_es/apigateway/latest/developerguide/images/success_icon.svg) Sí | 
| AES128-GCM-SHA256 | ![\[alt text not found\]](http://docs.aws.amazon.com/es_es/apigateway/latest/developerguide/images/success_icon.svg) Sí | 
| AES128-SHA256 | ![\[alt text not found\]](http://docs.aws.amazon.com/es_es/apigateway/latest/developerguide/images/success_icon.svg) Sí | 
| AES256-GCM-SHA384 | ![\[alt text not found\]](http://docs.aws.amazon.com/es_es/apigateway/latest/developerguide/images/success_icon.svg) Sí | 
| AES256-SHA256 | ![\[alt text not found\]](http://docs.aws.amazon.com/es_es/apigateway/latest/developerguide/images/success_icon.svg) Sí | 

## Nombre del cifrado OpenSSL y RFC
<a name="apigateway-secure-connections-openssl-rfc-cipher-names-websocket"></a>

OpenSSL e IETF RFC 5246 utilizan nombres distintos para los mismos cifrados. Para obtener una lista de los nombres de los cifrados, consulte [Nombre del cifrado OpenSSL y RFC](apigateway-security-policies-list.md#apigateway-secure-connections-openssl-rfc-cipher-names).

## Información acerca de las API de REST y las API HTTP
<a name="apigateway-websocket-additional-apis"></a>

Para obtener más información sobre las API de REST y las API HTTP, consulte [Elección de una política de seguridad para el dominio personalizado en API Gateway](apigateway-custom-domain-tls-version.md) y [Política de seguridad de las API de HTTP en API Gateway](http-api-ciphers.md).

# Nombres de dominio personalizados para las API de WebSocket en API Gateway
<a name="websocket-api-custom-domain-names"></a>

Los*nombres de dominio personalizados* son direcciones URL más sencillas e intuitivas que puede proporcionar a los usuarios de la API.

Después de implementar la API, usted (y sus clientes) puede invocar la API utilizando la URL base predeterminada con el siguiente formato: 

```
https://api-id.execute-api.region.amazonaws.com/stage
```

donde *api-id* lo genera API Gateway, *region* es la región de AWS y *stage* lo especifica usted al implementar la API.

La parte del nombre de host de la URL, `api-id.execute-api.region.amazonaws.com`, hace referencia a un punto de conexión de la API. El punto de conexión de la API predeterminado se genera aleatoriamente y no es muy descriptivo.

Con los nombres de dominio personalizados, puede configurar el nombre de host de la API y elegir una ruta base (por ejemplo, `myservice`) para asignarle una URL alternativa. Por ejemplo, una URL base de la API más simple puede ser:

```
https://api.example.com/myservice
```

## Consideraciones
<a name="websocket-api-custom-domain-names-considerations"></a>

Las siguientes consideraciones pueden afectar el uso de un nombre de dominio personalizado.
+ Si asigna un nombre de dominio personalizado a una API de WebSocket, no puede asignarlo a una API de REST o HTTP.
+ Solo se admiten nombres de dominio personalizados regionales.
+ Para la versión de TLS mínima, solo se admite TLS 1.2.
+ Debe crear o actualizar el registro de recursos del proveedor de DNS para asignarlo al punto de conexión de la API. Si no se realiza este mapeo, las solicitudes de API vinculadas al nombre de dominio personalizado no pueden llegar a API Gateway.
+ Puede admitir un número casi infinito de nombres de dominio sin exceder el límite predeterminado mediante el uso de un certificado comodín. Para obtener más información, consulte [Nombres de dominio personalizados comodín](http-api-custom-domain-names.md#http-wildcard-custom-domain-names).

## Requisitos previos
<a name="websocket-api-custom-domain-names-prerequisites"></a>

Los siguientes son requisitos previos para un nombre de dominio personalizado.

### Registrar un nombre de dominio
<a name="websocket-api-custom-domain-names-register"></a>

Debe disponer de un nombre de dominio de Internet registrado para poder crear nombres de dominio personalizados para sus API. Puede registrar su nombre de dominio de Internet con [Amazon Route 53](https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/) o un registrador de dominios de terceros de su elección. Su nombre de dominio personalizado puede ser el nombre de un subdominio o el dominio raíz (lo que recibe el nombre de “vértice de zona”) de un dominio de Internet registrado.

El nombre de dominio debe seguir la especificación [RFC 1035](https://tools.ietf.org/html/rfc1035#section-2.3.4) y puede tener un máximo de 63 octetos por etiqueta y 255 octetos en total.

### Certificados para nombres de dominio personalizados
<a name="websocket-api-custom-domain-names-certificates"></a>

Antes de configurar un nombre de dominio personalizado para una API, debe disponer de un certificado SSL/TLS listo en ACM. Si ACM no está disponible en la región de AWS donde va a crear su nombre de dominio personalizado, debe importar un certificado en API Gateway en esa región.

Para importar un certificado SSL/TLS, debe proporcionar el cuerpo del certificado SSL/TLS con formato PEM, su clave privada y la cadena de certificados para el nombre de dominio personalizado.

Los certificados almacenados en ACM se identifican mediante su ARN. Con los certificados emitidos por ACM no tiene que preocuparse de si se exponen datos del certificado confidenciales, como la clave privada. Para utilizar un certificado administrado por AWS para un nombre de dominio, solo tiene que hacer referencia a su ARN. 

Si la aplicación utiliza asignación de certificados, también conocido como asignación SSL, para asignar un certificado de ACM, es posible que la aplicación no se pueda conectar al dominio una vez que AWS renueva el certificado. Para obtener más información, consulte [Problemas de asignación de certificados](https://docs.aws.amazon.com/acm/latest/userguide/troubleshooting-pinning.html) en la *Guía del usuario de AWS Certificate Manager*.

## Nombres de dominio personalizados comodín
<a name="websocket-api-wildcard-custom-domain-names"></a>

Con los nombres de dominio personalizados comodín, puede admitir un número casi infinito de nombres de dominio sin exceder el [límite predeterminado](limits.md). Por ejemplo, puede dar a cada uno de los clientes su propio nombre de dominio, `customername.api.example.com`.

Para crear un nombre de dominio personalizado comodín, especifique un comodín (`*`) como primer subdominio de un dominio personalizado que represente todos los subdominios posibles de un dominio raíz.

Por ejemplo, el nombre de dominio personalizado comodín `*.example.com` produce subdominios como `a.example.com`, `b.example.com` y `c.example.com`, que enrutan al mismo dominio.

Los nombres de dominio personalizados comodín admiten configuraciones distintas de los nombres de dominio personalizados estándar de API Gateway. Por ejemplo, en una sola cuenta de AWS, puede configurar `*.example.com` y `a.example.com` para que se comporten de manera diferente.

Puede utilizar las variables de contexto `$context.domainName` y `$context.domainPrefix` para determinar el nombre de dominio que un cliente utilizó para llamar a la API. Para obtener más información acerca de las variables de contexto, consulte [Variables para transformaciones de datos para API Gateway](api-gateway-mapping-template-reference.md).

Para crear un nombre de dominio personalizado comodín, debe proporcionar un certificado emitido por ACM que se haya validado utilizando el método DNS o de validación de correo electrónico.

**nota**  
No se puede crear un nombre de dominio personalizado comodín si una cuenta de AWS diferente ha creado un nombre de dominio personalizado que entra en conflicto con el nombre de dominio personalizado comodín. Por ejemplo, si la cuenta A ha creado `a.example.com`, la cuenta B no puede crear el nombre de dominio personalizado comodín `*.example.com`.  
Si la cuenta A y la cuenta B comparten un propietario, puede contactar con el [Centro de soporte de AWS](https://console.aws.amazon.com/support/home#/) para solicitar una excepción.

## Siguientes pasos para nombres de dominio personalizados
<a name="websocket-api-custom-domain-names-next-steps"></a>

Para configurar un nombre de dominio personalizado para una API de HTTP, utilice la sección API de REST de la Guía para desarrolladores de API Gateway. 

En primer lugar, especifique el certificado para el nombre de dominio personalizado. Para obtener más información, consulte [Preparación de certificados en AWS Certificate Manager](how-to-specify-certificate-for-custom-domain-name.md). A continuación, cree un nombre de dominio personalizado regional. Para obtener más información, consulte [Configuración de un nombre de dominio personalizado regional en API Gateway](apigateway-regional-api-custom-domain-create.md).

# Asignación de etapas de API a un nombre de dominio personalizado para las API de WebSocket
<a name="websocket-api-mappings"></a>

Los mapeos de la API se utilizan para conectar etapas de la API a un nombre de dominio personalizado. Después de crear un nombre de dominio y configurar registros DNS, se utilizan mapeos de la API para enviar tráfico a las API a través del nombre de dominio personalizado.

Un mapeo de la API especifica una API, una etapa y, de forma opcional, una ruta que se utilizará para el mapeo. Por ejemplo, puede mapear la etapa de `production` de una API a `wss://api.example.com/orders`.

Antes de crear un mapeo de la API, debe tener una API, una etapa y un nombre de dominio personalizado. Para obtener más información sobre cómo crear un nombre de dominio personalizado, consulte [Configuración de un nombre de dominio personalizado regional en API Gateway](apigateway-regional-api-custom-domain-create.md).

## Restricciones
<a name="websocket-api-mappings-restrictions"></a>
+ En un mapeo de la API, el nombre de dominio personalizado y las API mapeadas deben estar en la misma cuenta de AWS.
+ Los mapeos de la API deben contener solo letras, números y los siguientes caracteres: `$-_.+!*'()`.
+ La longitud máxima de la ruta en un mapeo de la API es de 300 caracteres.
+ No puede mapear las API de WebSocket al mismo nombre de dominio personalizado que una API HTTP o API REST.
+ Si crea una asignación de API con varios niveles, API Gateway convierte todos los nombres de encabezado a minúsculas.

## Creación de un mapeo de la API
<a name="websocket-api-mappings-examples"></a>

Para crear un mapeo de la API, primero debe crear un nombre de dominio personalizado, una API y una etapa. Para obtener información sobre cómo crear un nombre de dominio personalizado, consulte [Configuración de un nombre de dominio personalizado regional en API Gateway](apigateway-regional-api-custom-domain-create.md).

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

**Para crear un mapeo de la API**

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 **Custom domain names** (Nombres de dominio personalizados).

1. Seleccione un nombre de dominio personalizado que ya haya creado.

1. Elija **API mappings** (Mapeos de la API).

1. Elija **Configure API mappings (Configurar asignaciones de API)**.

1. Seleccione **Add new mapping (Agregar nueva asignación)**.

1. Introduzca una **API**, una **Stage** (Etapa) y, de forma opcional, una **Path** (Ruta).

1. Seleccione **Guardar**.

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

El siguiente comando [create-api-mapping](https://docs.aws.amazon.com/cli/latest/reference/apigatewayv2/create-api-mapping.html) permite crear una asignación de API. En este ejemplo, API Gateway envía solicitudes a `api.example.com/v1` a la API y a la etapa especificada.

```
aws apigatewayv2 create-api-mapping \
    --domain-name api.example.com \
    --api-mapping-key v1 \
    --api-id a1b2c3d4 \
    --stage test
```

------
#### [ CloudFormation ]

El siguiente ejemplo de CloudFormation crea un mapeo de la API.

```
MyApiMapping:
  Type: 'AWS::ApiGatewayV2::ApiMapping'
  Properties:
    DomainName: api.example.com
    ApiMappingKey: 'v1'
    ApiId: !Ref MyApi
    Stage: !Ref MyStage
```

------

# Tipos de direcciones IP para nombres de dominio personalizados para API de WebSocket
<a name="websocket-api-custom-domain-names-ip-address-type"></a>

Al crear un nombre de dominio personalizado, se especifica el tipo de direcciones IP que puede invocar el dominio. Puede elegir IPv4 para resolver las direcciones IPv4 para invocar el dominio o puede elegir pila doble para permitir que las direcciones IPv4 e IPv6 invoquen el dominio. 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-custom-domain-names-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 los nombres de dominio personalizados de API Gateway es IPv4.
+ El nombre de dominio personalizado no necesita tener el mismo tipo de dirección IP para todas las API asignadas a él. 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 del nombre de dominio personalizado
<a name="websocket-api-custom-domain-names-ip-address-type-change"></a>

Puede cambiar el tipo de dirección IP actualizando la configuración de punto de conexión del nombre de dominio. Puede actualizar la configuración de punto de conexión mediante el uso de la Consola de administración de AWS, la AWS CLI, CloudFormation, o un AWS SDK.

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

**Cambio del tipo de dirección IP de un nombre de dominio personalizado**

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 un nombre de dominio personalizado público.

1. Elija la **Configuración de punto de conexión**.

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

1. Seleccione **Save**.

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

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

```
aws apigatewayv2 update-domain-name \
   --domain-name dualstack.example.com \
   --domain-name-configurations CertificateArn=arn:aws:acm:us-east-1:111122223333:certificate/abcd1234-5678-abc,IpAddressType=dualstack
```

El resultado será similar al siguiente:

```
{
    "ApiMappingSelectionExpression": "$request.basepath",
    "DomainName": "dualstack.example.com",
    "DomainNameConfigurations": [
        {
            "ApiGatewayDomainName": "d-abcd1234.execute-api.us-east-1.amazonaws.com",
            "CertificateArn": "arn:aws:acm:us-east-1:111122223333:certificate/abcd1234-5678-abc",
            "DomainNameStatus": "AVAILABLE",
            "EndpointType": "REGIONAL",
            "HostedZoneId": "Z3LQWSYCGH4ADY",
            "SecurityPolicy": "TLS_1_2",
            "IpAddressType": "dualstack"
        }
    ],
    "Tags": {}
}
```

------

# Deshabilitación del punto de conexión predeterminado para las API de WebSocket
<a name="websocket-api-disable-default-endpoint"></a>

De forma predeterminada, los clientes pueden invocar su API mediante el punto de conexión `execute-api` que API Gateway genera para ella. Para asegurarse de que los clientes solo puedan acceder a su API mediante un nombre de dominio personalizado, deshabilite el punto de conexión predeterminado `execute-api`. Cuando deshabilita el punto de conexión predeterminado, esto afecta a todas las etapas de una API.

El siguiente procedimiento muestra cómo deshabilitar el punto de conexión predeterminado para una API de WebSocket.

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

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**.

1. En **Detalles de API**, elija **Editar**.

1. En **Punto de conexión predeterminado**, elija **Inactivo**.

1. Elija **Guardar cambios**.

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

1. Elija **Implementar** y, a continuación, vuelva a implementar la API o cree una nueva etapa para que el cambio surta efecto.

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

El siguiente comando [update-api](https://docs.aws.amazon.com/cli/latest/reference/apigatewayv2/update-api.html) desactiva el punto de conexión predeterminado de una API de WebSocket.

```
aws apigatewayv2 update-api \
    --api-id abcdef123 \
    --disable-execute-api-endpoint
```

Después de desactivar el punto de conexión predeterminado, debe implementar la API para que el cambio surta efecto.

El siguiente comando de la AWS CLI crea una implementación.

```
aws apigatewayv2 create-deployment \
    --api-id abcdef123 \
    --stage-name dev
```

------

# Protección de las API de WebSocket en API Gateway
<a name="websocket-api-protect"></a>

API Gateway proporciona una serie de formas de proteger su API de ciertas amenazas, como usuarios malintencionados o picos de tráfico. Puede proteger la API mediante estrategias como generar certificados SSL o establecer objetivos de limitación. Para obtener más información acerca de cómo generar certificados SSL, consulte [Generación y configuración de un certificado SSL para la autenticación de backend en API Gateway](getting-started-client-side-ssl-authentication.md). El resto de esta sección trata sobre cómo establecer objetivos de limitación.

Puede configurar la limitación de las API para evitar que se vean desbordadas por un número excesivo de solicitudes. La limitación se aplica como medida compensatoria y se debe considerar como un valor objetivo, más que como un límite de solicitudes garantizado.

API Gateway limita las solicitudes a la API utilizando el algoritmo de bucket de tokens, donde un token cuenta por una solicitud. En concreto, API Gateway examina el ratio de solicitudes y una ráfaga de envíos de solicitudes para todas las API de su cuenta, por región. En el algoritmo de bucket de tokens, una ráfaga puede permitir que se sobrepasen los límites predefinidos, pero también hay otros factores que pueden hacer que se sobrepasen los límites en algunos casos.

Cuando los envíos de solicitudes superan los límites de ratio de solicitudes en estado estable y de ráfaga, API Gateway comienza a limitar las solicitudes. Los clientes pueden recibir respuestas de error `429 Too Many Requests` en este momento. Tras capturar estas excepciones, el cliente puede reenviar las solicitudes que han producido un error de forma que limite el ratio.

Como desarrollador de la API, puede configurar los límites objetivos para las etapas o rutas individuales de la API con el fin de mejorar el rendimiento general de todas las API de su cuenta.

## Limitación de nivel de cuenta por región
<a name="websocket-api-protect-throttling-account"></a>

De forma predeterminada, API Gateway limita las solicitudes de estado constante por segundo (RPS) en todas las API de una cuenta de AWS, por región. También limita la ráfaga (es decir, el tamaño máximo del bucket) en todas las API dentro de una cuenta de AWS, por región. En API Gateway, el límite de ráfaga representa el número máximo de envíos de solicitudes simultáneas que API Gateway; abordará antes de devolver respuestas de error `429 Too Many Requests`. Para obtener más información sobre las cuotas de limitación, consulte [Cuotas de Amazon API Gateway](limits.md).

Los límites por cuenta se aplican a todas las API de una cuenta en una región determinada. El límite de ratio de nivel de cuenta se puede aumentar previa solicitud. Los límites más altos son posibles con API que tienen tiempos de espera más cortos y cargas útiles más pequeñas. Para solicitar un aumento de los límites de limitación de nivel de cuenta por región, contacte con el [Centro de soporte de AWS](https://console.aws.amazon.com/support/home#/). Para obtener más información, consulte [Cuotas de Amazon API Gateway](limits.md). Tenga en cuenta que estos límites no pueden ser superiores a los límites de limitación de AWS.

## Limitación de nivel de ruta
<a name="websocket-api-protect-throttling-route"></a>

Puede definir la limitación de nivel de ruta para invalidar los límites de limitación de las solicitudes de nivel de cuenta de una determinada etapa o de las rutas individuales de la API. Los límites de limitación de rutas predeterminados no pueden superar los límites de ratio a nivel de cuenta.

Puede configurar la limitación de nivel de ruta mediante la AWS CLI. El siguiente comando [update-stage](https://docs.aws.amazon.com/cli/latest/reference/apigatewayv2/update-stage.html) permite configurar la limitación de nivel de ruta para la etapa y la ruta especificadas de una API.

```
aws apigatewayv2 update-stage \
    --api-id a1b2c3d4 \
    --stage-name dev \
    --route-settings '{"messages":{"ThrottlingBurstLimit":100,"ThrottlingRateLimit":2000}}'
```

# Supervisión de las API de WebSocket en API Gateway
<a name="websocket-api-monitor"></a>

Puede utilizar las métricas de CloudWatch y CloudWatch Logs para monitorear las API de WebSocket. Al combinar registros y métricas, puede registrar errores y monitorear el rendimiento de su API.

**nota**  
API Gateway podría no generar registros y métricas en los siguientes casos:  
Errores 413: Entidad de solicitud demasiado grande
Errores 429: Demasiadas Solicitudes
Errores de la serie 400 de solicitudes enviadas a un dominio personalizado que no tiene asignación de API
Errores de la serie 500 causados por errores internos

**Topics**
+ [Supervisión de la ejecución de la API de WebSocket con métricas de CloudWatch](apigateway-websocket-api-logging.md)
+ [Configuración del registro de las API de WebSocket en API Gateway](websocket-api-logging.md)

# Supervisión de la ejecución de la API de WebSocket con métricas de CloudWatch
<a name="apigateway-websocket-api-logging"></a>

Puede usar métricas de [Amazon CloudWatch](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/WhatIsCloudWatch.html) para monitorear las API de WebSocket. La configuración es similar a la utilizada para las API de REST. Para obtener más información, consulte [Supervisión de la ejecución de la API de REST con métricas de Amazon CloudWatch](monitoring-cloudwatch.md).

Las siguientes métricas se admiten para las API de WebSocket:


| Métrica | Descripción | 
| --- | --- | 
| ConnectCount | El número de mensajes enviados a la integración de ruta \$1connect. | 
| MessageCount | El número de mensajes enviados a la API de WebSocket, con origen o destino en el cliente. | 
| IntegrationError | El número de solicitudes que devuelven una respuesta 4XX/5XX desde la integración. | 
| ClientError | El número de solicitudes para las que API Gateway devuelve una respuesta 4XX antes de que se invoque la integración. | 
| ExecutionError | Errores que se han producido al llamar a la integración. | 
| IntegrationLatency | El tiempo que transcurre entre el momento en que API Gateway envía la solicitud a la integración y el momento en que API Gateway recibe la respuesta de la integración. Se suprime para devoluciones de llamada e integraciones simuladas. | 

Puede usar las dimensiones de la tabla siguiente para filtrar las métricas de API Gateway.


| Dimensión | Descripción | 
| --- | --- | 
| ApiId | Filtra las métricas de API Gateway para una API con el ID de API especificado. | 
| ApiId, Stage | Filtra las métricas de API Gateway para una etapa de API cuyos ID de API y de etapa se hayan especificado. | 
| ApiId, método, recurso, etapa |  Filtra las métricas de API Gateway para un método de API con el ID de API, el ID de etapa, la ruta de recursos y el ID de enrutamiento específicos. API Gateway no enviará estas métricas a menos que haya habilitado explícitamente las métricas detalladas de CloudWatch. Puede hacerlo mediante una llamada a la acción [UpdateStage](https://docs.aws.amazon.com/apigatewayv2/latest/api-reference/apis-apiid-stages-stagename.html) de la API de REST de API Gateway V2 para actualizar la propiedad `detailedMetricsEnabled` en `true`. También puede llamar al comando [update-stage](https://docs.aws.amazon.com/cli/latest/reference/apigatewayv2/update-stage.html) AWS CLI para actualizar la propiedad `DetailedMetricsEnabled` a `true`. Si activa estas métricas, se le cobrarán cargos adicionales en su cuenta. Para obtener más información sobre precios, consulte [Precios de Amazon CloudWatch](https://aws.amazon.com/cloudwatch/pricing/).  | 

# Configuración del registro de las API de WebSocket en API Gateway
<a name="websocket-api-logging"></a>

Puede habilitar el registro para escribir registros en CloudWatch Logs. Existen dos tipos de registro de API en CloudWatch: los registros de ejecución y los registros de acceso. En el registro de ejecución, API Gateway administra los CloudWatch Logs. El proceso incluye la creación de grupos y flujos de registros y la notificación a los flujos de registro de las solicitudes y respuestas del intermediario. 

Para aumentar la seguridad, le recomendamos que utilice el registro de ejecución en el nivel `INFO` o `ERROR`. Es probable que deba hacerlo para asegurar el cumplimiento de 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*.

En los registros de acceso, tanto usted como el desarrollador de la API pretenden registrar quién ha obtenido acceso a la API y cómo el intermediario ha obtenido acceso a la API. Puede crear su propio grupo de registros o elegir un grupo de registros existente, que podría administrarse a través de API Gateway. Para especificar los detalles de acceso, seleccione variables `$context` (expresadas en un formato que elija) y elija un grupo de registro como destino.

Para ver instrucciones sobre cómo configurar el registro de CloudWatch, consulte [Configuración del registro de API de CloudWatch mediante la consola de API Gateway](set-up-logging.md#set-up-access-logging-using-console).

Al especificar el **Log Format (Formato de registro)**, puede elegir las variables de contexto que deben registrarse. Se admiten las siguientes variables.


| Parámetro | Descripción | 
| --- | --- | 
| \$1context.apiId |  El identificador que API Gateway asigna a su API.  | 
| \$1context.authorize.error | El mensaje de error de autorización. | 
| \$1context.authorize.latency | La latencia de autorización en ms. | 
| \$1context.authorize.status | El código de estado devuelto por un intento de autorización. | 
| \$1context.authorizer.error | El mensaje de error devuelto por un autorizador. | 
| \$1context.authorizer.integrationLatency | La latencia del autorizador de Lambda en ms. | 
| \$1context.authorizer.integrationStatus | El código de estado que devuelve un autorizador de Lambda. | 
| \$1context.authorizer.latency | La latencia del autorizador en ms. | 
| \$1context.authorizer.requestId | El ID de solicitud del punto de conexión de AWS. | 
| \$1context.authorizer.status | El código de estado devuelto por un autorizador. | 
| \$1context.authorizer.principalId |  La identificación de usuario principal que está asociada con el token que envía el cliente y devuelve la función de Lambda del autorizador personalizado de Lambda de API Gateway. (El autorizador de Lambda se conocía anteriormente como “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.authenticate.error | El mensaje de error devuelto por un intento de autorización. | 
| \$1context.authenticate.latency | La latencia de autenticación en ms. | 
| \$1context.authenticate.status | El código de estado devuelto por un intento de autenticación. | 
| \$1context.connectedAt |  Hora de la conexión en [formato de tiempo Unix](https://en.wikipedia.org/wiki/Unix_time).  | 
| \$1context.connectionId |  Identificador único para la conexión que se puede utilizar para realizar una devolución de llamada al cliente.  | 
| \$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.error.message |  Una cadena que contiene un mensaje de error de API Gateway.  | 
| \$1context.error.messageString | El valor entrecomillado de \$1context.error.message, es decir, "\$1context.error.message". | 
| \$1context.error.responseType |  El tipo de respuesta de error.  | 
| \$1context.error.validationErrorString |  Una cadena que contiene un mensaje de error de validación detallado.  | 
| \$1context.eventType |  El tipo de evento: `CONNECT`, `MESSAGE` o `DISCONNECT`.  | 
| \$1context.extendedRequestId | Es igual que \$1context.requestId. | 
| \$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 firmó la solicitud. Compatible con rutas que utilizan la autorización de IAM.  | 
| \$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.principalOrgId |  El [ID de organización de AWS](https://docs.aws.amazon.com/organizations/latest/userguide/orgs_manage_org_details.html). Compatible con rutas que utilizan la autorización de IAM.  | 
| \$1context.identity.sourceIp |  La dirección IP de origen de la conexión TCP que realiza la solicitud de API Gateway.  | 
| \$1context.identity.user |  El identificador principal del usuario que se autorizará a acceder al recurso. Compatible con rutas que utilizan la autorización de IAM.  | 
| \$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.integration.error | El mensaje de error devuelto por una integración. | 
| \$1context.integration.integrationStatus | Para la integración de proxy de Lambda, el código de estado que se devuelve desde AWS Lambda, y no desde el código de función de Lambda del backend. | 
| \$1context.integration.latency | La latencia de integración en ms. Es igual que \$1context.integrationLatency. | 
| \$1context.integration.requestId | El ID de solicitud del punto de conexión de AWS. Es igual que \$1context.awsEndpointRequestId. | 
| \$1context.integration.status | El código de estado devuelto por una integración. Para integraciones de proxy de Lambda, este es el código de estado que devuelve su código de la función de Lambda. Es igual que \$1context.integrationStatus. | 
| \$1context.integrationLatency | La latencia de integración en ms, disponible únicamente para el registro de acceso. | 
| \$1context.messageId |  Un ID único del lado del servidor para un mensaje. Solo está disponible si `$context.eventType` es `MESSAGE`.  | 
| \$1context.requestId |  Igual que `$context.extendedRequestId`.  | 
| \$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.routeKey |  La clave de ruta seleccionada.  | 
| \$1context.stage |  La etapa de implementación de la llamada a la API (por ejemplo, beta o prod).  | 
| \$1context.status |  Estado de la respuesta.  | 
| \$1context.waf.error | El mensaje de error devuelto por AWS WAF. | 
| \$1context.waf.latency | La latencia de AWS WAF en ms. | 
| \$1context.waf.status | El código de estado devuelto por AWS WAF. | 

Algunos ejemplos de los formatos de registro de acceso que se utilizan habitualmente se muestran en la consola de API Gateway y se detallan a continuación.
+ `CLF` ([Common Log Format](https://httpd.apache.org/docs/current/logs.html#common)):

  ```
  $context.identity.sourceIp $context.identity.caller \
  $context.identity.user [$context.requestTime] "$context.eventType $context.routeKey $context.connectionId" \
  $context.status $context.requestId
  ```

  Los caracteres de continuación (`\`) deben entenderse como una ayuda visual. El formato de registro debe ser una sola línea. Puede agregar un carácter de nueva línea (`\n`) al final del formato de registro para incluir una nueva línea al final de cada entrada de registro.
+  `JSON`: 

  ```
  {
  "requestId":"$context.requestId", \
  "ip": "$context.identity.sourceIp", \
  "caller":"$context.identity.caller", \
  "user":"$context.identity.user", \
  "requestTime":"$context.requestTime", \
  "eventType":"$context.eventType", \
  "routeKey":"$context.routeKey", \
  "status":"$context.status", \
  "connectionId":"$context.connectionId"
  }
  ```

  Los caracteres de continuación (`\`) deben entenderse como una ayuda visual. El formato de registro debe ser una sola línea. Puede agregar un carácter de nueva línea (`\n`) al final del formato de registro para incluir una nueva línea al final de cada entrada de registro.
+ `XML`: 

  ```
  <request id="$context.requestId"> \
   <ip>$context.identity.sourceIp</ip> \
   <caller>$context.identity.caller</caller> \
   <user>$context.identity.user</user> \
   <requestTime>$context.requestTime</requestTime> \
   <eventType>$context.eventType</eventType> \
   <routeKey>$context.routeKey</routeKey> \
   <status>$context.status</status> \
   <connectionId>$context.connectionId</connectionId> \
  </request>
  ```

  Los caracteres de continuación (`\`) deben entenderse como una ayuda visual. El formato de registro debe ser una sola línea. Puede agregar un carácter de nueva línea (`\n`) al final del formato de registro para incluir una nueva línea al final de cada entrada de registro.
+ `CSV` (valores separados por comas):

  ```
  $context.identity.sourceIp,$context.identity.caller, \
  $context.identity.user,$context.requestTime,$context.eventType, \
  $context.routeKey,$context.connectionId,$context.status, \
  $context.requestId
  ```

  Los caracteres de continuación (`\`) deben entenderse como una ayuda visual. El formato de registro debe ser una sola línea. Puede agregar un carácter de nueva línea (`\n`) al final del formato de registro para incluir una nueva línea al final de cada entrada de registro.