El 30 de octubre de 2024, AWS anunció una nueva función: AppSync Events. Esta función permite a los desarrolladores transmitir fácilmente datos de eventos en tiempo real a unos pocos suscriptores o a millones de ellos mediante API Serverless WebSocket seguras y de alto rendimiento. Pero espere, ¿no teníamos ya Serverless WebSockets con API API Gateway WebSocket? Bueno, sí, pero no exactamente así.
En esta publicación, aprenderá sobre los eventos de AppSync. Cubriré sus aspectos básicos y brindaré mi opinión sobre su futuro, casos de uso, uso y en qué se diferencia de los Websockets de API Gateway. También proporcionaré un repositorio de JavaScript en GitHub para que pueda experimentar con él usted mismo.
Tabla de contenido
¿Qué es un WebSocket?
WebSocket es un protocolo de comunicación informática que proporciona un canal de comunicación bidireccional simultáneo a través de una única conexión de Protocolo de control de transmisión (TCP) - Wikipedia
Los web sockets no son nada nuevo. Se utilizan en todas las aplicaciones sociales de tu teléfono y en numerosos sitios web que muestran resultados en vivo y actualizaciones en tiempo real. ¿Alguna vez te preguntaste cómo tu pestaña de Chrome se actualiza mágicamente con nueva información? No, no es un sondeo. Son WebSockets. El backend de la aplicación envía una actualización (ya sea una transmisión/unicast/multicast) al web socket de tu navegador.
Si bien el protocolo tiene su propia implementación sobre TCP, comienza su protocolo de enlace sobre el protocolo HTTP y luego se "actualiza" al protocolo WebSocket, donde hace lo suyo de acuerdo con el RFC .
Si quieres saber más sobre el protocolo mira el vídeo a continuación:
Pasemos a los eventos de AppSync.
¿Qué es AppSync Events?
AWS AppSync Events le permite crear API WebSocket sin servidor seguras y de alto rendimiento que pueden transmitir datos de eventos en tiempo real a millones de suscriptores, sin que usted tenga que administrar conexiones o escalar recursos. - AWS
En primer lugar, dejemos algo en claro: esto no tiene nada que ver con GraphQL y AppSync.
Es simplemente una mala imagen de marca para esta nueva interpretación de websockets sin servidor.
Conceptos básicos y terminología
Los eventos de AppSync se interpretan de manera diferente en WebSockets, tanto en el nivel de protocolo físico como en la administración sin servidor y la interpretación de mensajes.
Según tengo entendido, según la documentación , agregaron otra capa de abstracción, un subprotocolo interno (AppSync-y) para administrar una nueva entidad de canal sobre un único WebSocket. Esto se puede ver en el diagrama de la guía para desarrolladores de AWS :
Una vez que los clientes se conectan al punto final de AppSync, pueden intentar suscribirse a un canal .
El truco genial aquí es conectarse a múltiples canales en el mismo socket web. Da la ilusión de numerosos temas/canales de " publicación y suscripción ", pero en realidad es el mismo socket web abstracto. ¡Buen detalle!
La suscripción requiere autorización y hay cinco opciones:
Estas opciones cubren todos los métodos de autorización estándar . Normalmente opto por una función Lambda que comprueba la cookie segura de la aplicación web y JWT , además de verificaciones adicionales.
La documentación entra en muchos detalles e incluso proporciona un ejemplo de esquema de entrada de función Lambda y una implementación de muestra: ¡impresionante!
Volviendo al tema de los canales, existe el canal predeterminado / , pero puedes agregar más canales. Un espacio de nombres de canal se compone de un máximo de cinco segmentos, lo que ofrece un alto grado de flexibilidad. Piensa en ellos como subtemas de publicación orientados a la interfaz de usuario.
Por ejemplo, puedes crear un canal para actualizaciones generales de usuarios o por categorías, como NBA, fútbol, etc. La capacidad de usar hasta cinco segmentos te da la posibilidad de publicar actualizaciones sobre diferentes deportes, como /users/nba y /users/football .
Además, puedes suscribirte a /users/nba/ para recibir noticias generales de la NBA, o puedes suscribirte a /users/nba/* (¡comodín!), lo que significa que obtienes todas las noticias de la NBA de los subsegmentos como /users/nba/bulls y /users/nba/lakers.
En lo que respecta a la publicación, esto se puede hacer tanto desde el frontend como desde el backend y requiere autorización. Puedes establecer un método de autorización diferente por canal y usar una función Lambda (¡un buen detalle!). Si tienes permiso para publicar mensajes en estos canales, solo necesitas enviar una solicitud HTTP a la dirección del canal (y de los segmentos). Puedes publicar desde una función Lambda o Event Bridge ( destino de API , supongo) convirtiendo AppSync Events en un habilitador de arquitectura impulsado por eventos.
Primeras impresiones y uso
Seguí la consola y la documentación y creé mi primera API de eventos. No recuerdo la última vez que vi una documentación tan bien hecha para un nuevo lanzamiento. Hay soporte para muchos autorizadores e incluso ejemplos de código para el lado del cliente. Una característica que falta de forma evidente es la compatibilidad con CDK, que es solo una L1. Al momento de escribir esto, hay un problema abierto para CDK L2. Comencé con lo básico: la autorización de clave API no muy segura.
No utilicé el editor de publicaciones y subeditores de la consola. Me puse a jugar directamente con una aplicación web e intenté suscribirme a un canal y publicar en él. Utilicé los ejemplos de código de la consola y funcionó.
Tuve algunos problemas menores porque soy un completo novato en frontend, pero después de la ayuda de mi increíble colega Afik Grinstein , tuvimos un proyecto Vite funcionando .
El repositorio completo de GitHub se encuentra en https://github.com/ran-isenberg/appsync-events-client .
Repasemos lo que construimos:
Nuestro cliente se suscribe al canal y segmento 'predeterminado/de prueba'. Una vez suscrito, publica eventos a través de la sección de entrada de texto de la interfaz de usuario de publicación.
La sección de registros de eventos muestra todos los mensajes publicados en '/default/test'.
y sí, es realmente un websocket con protocolo AppSync dentro:
y:
Aquí está el código JS, bastante simple cuando se usa Amplify SDK:
Pude suscribirme a otro canal, por ejemplo, '/users', y verificar la suscripción con comodín. Sí, funciona y es muy fácil. Cuando se trabaja con canales de unidifusión o específicos del cliente, debe agregar una autorización personalizada para verificar si el usuario puede suscribirse a ese mensaje de ID de usuario/inquilino.
De todas formas, honestamente, esto es impresionante, simplemente funciona.
Si estás interesado en el código completo y el archivo HTML, está aquí .
Pasemos a la sección de insights donde la cosa se pone interesante.
Información y consejos
En esta sección, compartiré algunas ideas obtenidas al usar el servicio durante varias horas, lo que conducirá al resumen y la conclusión: ¿lo usaré o no?
Seguridad
Me gusta la flexibilidad de las opciones de autorización. Cinco tipos de autorización para la conexión inicial y una autorización adicional para suscripciones específicas de canales son más que suficientes.
También puede agregar un método de autorización de conexión por canal y ajustarlo para solicitudes de publicación y suscripción con un Lambda de su elección. Aquí hay un ejemplo de controlador .
Hay compatibilidad con AWS WAF, que no existe para API Gateway Websockets. Es obligatoria, ya que estamos exponiendo un punto de conexión HTTP para publicar mensajes.
Consulte mi publicación de blog aquí para obtener más información sobre AWS WAF.
Sin tablas de conexión
No es necesario administrar tablas de conexión; ¡es genuinamente sin servidor!
Si no tienes idea de por qué estoy sorprendido, es porque cuando usas API Gateway WebSockets, cuando quieres enviar un mensaje a un usuario, necesitas saber su ID de conexión de web socket. Esta asignación es visible durante el proceso de protocolo de enlace ($connect) cuando autenticas al usuario y permites la conexión, lo que significa que necesitas guardarla en algún lugar para tu servicio de backend. DynamoDB es una excelente opción para almacenar esta información de clave-valor, pero es un código que necesitas agregar, escribir, mantener y probar. No es gran cosa, pero AWS no nos lo dio listo para usar. Aquí está resumido. No sabes el ID de conexión (y estoy seguro de que hay uno); hablas los idiomas de los canales. Ni siquiera sabes quién está conectado a los canales; la suposición aquí es que ni siquiera te importa. Quieres publicar un mensaje en un canal, y quien esté suscrito recibirá ese mensaje. Pub-sub clásico.
En resumen, se trata de un enfoque diferente: canal vs. identificación de conexión.
La difusión masiva es fácil
Con los sockets de API Gateway, debe iterar la tabla de conexión, obtener los identificadores de conexión relevantes y, luego, usar el SDK de AWS para publicar un mensaje. Debe manejar errores, reintentos y limitaciones, y esto se vuelve muy complicado a medida que aumenta la lista de audiencia de destino.
Con AppSync Events, todo lo que necesitas hacer es realizar UNA llamada API a un punto final HTTP con la autorización correcta : ¡increíble! Es muy simple .
Sin embargo, no tienes ninguna información sobre qué usuarios recibieron o no el mensaje. Con los web sockets de API GW, si publicas en un ID de conexión cerrado, recibes una excepción y lo sabes. Tal vez eso no sea importante para tu caso de uso, pero debes tenerlo en cuenta.
Estimado equipo de AppSync Events: Tengo una sugerencia. ¿Qué sucedería si pudiera haber una función de cola de mensajes para los canales? Una función en la que canales específicos (/usuarios) almacenen datos durante un tiempo predefinido incluso si los usuarios cierran la sesión. Luego, cuando se restablezca la suscripción del canal (/usuarios/
El aislamiento de inquilinos y usuarios requiere diseño de canales
La unidifusión es más difícil (en cierta medida, pero no mucho). Digamos que necesito enviar mensajes específicos de usuario a través del websocket y todos los mensajes generales de los clientes, pero son específicos del cliente y no se pueden enviar a todos.
Nuestro espacio de nombres de canales podría verse así: los usuarios se suscriben a '/tenant/
Tenga en cuenta que los espacios de nombres de los canales no son infinitos. Hay un límite de 50, pero es un vínculo simbólico.
Además, cada espacio de nombres tiene una limitación de 50 caracteres, así que preste atención cuando agregue identificaciones de inquilino o identificaciones de usuario al juego: un UUID estándar tiene 36 caracteres.
(Exceso de) flexibilidad significa complejidad
Diseñar canales y autorizar a los usuarios a utilizarlos agrega complejidad. Debe comprender cómo modelarlos; recordar qué tipo de datos (personales o no) se incluyen en cada lugar, porque aquí no hay protección. Debe crearlos. Debe incorporar la lógica en su autorización de canal personalizada. También debe asegurarse de que sus clientes front-end se suscriban a los canales correctos. Además, cuantas más entidades agregue al sistema, más cambios de código deberá realizar: si agrega una persona "administradora", es posible que deba agregar un nuevo espacio de nombres o una suscripción diferente/adicional con todos sus controladores de autorización actualizados.
Es mucho más complicado que en la API GW WebSockets, donde te conectas y escuchas mensajes. Claro, necesito crear una tabla DynamoDB que mantenga una asignación entre el ID de conexión, el ID de usuario y el ID de sesión, pero eso es bastante básico.
Experiencia del desarrollador
La documentación es buena, pero no perfecta. El soporte de CDK es muy limitado. faltante .
El subeditor de publicaciones es un buen detalle para probar rápidamente un canal y su autorización. Sin embargo, no espero que los desarrolladores de backend trabajen en la consola a diario. Es una buena opción para los desarrolladores que desean probar un nuevo canal y ver datos de su editor de backend.
Los ejemplos de código de Amplify son buenos, me ayudaron a empezar rápidamente. Si no usas su SDK, puedes usar la API de eventos, pero tendrás que agregar todos los encabezados de AppSync en los lugares correctos.
Por último, debes usar el controlador de eventos JavaScript integrado para los controladores de canales personalizados " onSubscribe" y "onPublish". No puedes incorporar tu propia función o dependencias. En mi opinión, no es la mejor experiencia.
Precios
Como mencionó Jeremy Daly:
El precio es tres veces más barato que el de API Gateway WebSockets por minuto de conexión: 0,08 USD por millón de minutos de conexión para AppSync, frente a los 0,25 USD por millón de API Gateway. Las transferencias de mensajes parecen ser las mismas, pero AppSync parece cobrarte por cada "operación".
También hay un generoso nivel gratuito.
En mi opinión, esto supone una victoria para AppSync frente a API Gateway.
Resumen: ¿Si se hace bien o de manera diferente? O, en otras palabras, ¿lo usaré?
AppSync Events es una nueva versión de Serverless WebSockets. Agrega complejidad a la autorización y la gestión de canales, pero soluciona la principal desventaja de usar los web sockets de API GW para la difusión masiva.
Si no necesita una difusión masiva y siempre envía mensajes específicos para el usuario, los websockets API GW habituales son una opción sólida y probada. ¡Pronto escribiré una entrada de blog al respecto con ejemplos de código CDK también!
El servicio tiene un futuro prometedor y mucho potencial. Lo recomiendo encarecidamente para pruebas de concepto, empresas emergentes y otras empresas que estén dispuestas a ser pioneras en la adopción.
Sin embargo, como arquitecto empresarial, debo pensarlo detenidamente. La experiencia del desarrollador no es muy buena, gov-cloud aún no es compatible y ser uno de los primeros en adoptarlo significa que el servicio puede dejar de funcionar o cambiar de repente. Además, a juzgar por el pasado, por ejemplo, Evidently y AppConfig parecían hacer el mismo conjunto de funciones, pero con algunas diferencias, y al final, AppConfig se mantuvo y Evidently no . Por cierto, si quieres aprender más sobre AppConfig para indicadores de funciones, consulta mi publicación aquí .
Pero quién sabe, tal vez sea al revés. Tal vez los web sockets de API Gateway queden obsoletos con el tiempo. Todo depende de la adopción de AppSync Events y de la mejora de la experiencia y la documentación de los desarrolladores por parte del equipo de servicio.