Em 30 de outubro de 2024, a AWS anunciou um novo recurso: AppSync Events. Esse recurso permite que os desenvolvedores transmitam facilmente dados de eventos em tempo real para alguns ou milhões de assinantes usando APIs Serverless WebSocket seguras e de alto desempenho. Mas espere, já não tínhamos soquetes da Web Serverless com APIs API Gateway Websocket? Bem, sim, mas não exatamente assim.
Neste post, você aprenderá sobre AppSync Events. Abordarei seus conceitos básicos e darei minha opinião sobre seu futuro, casos de uso, uso e como ele difere dos Websockets do API Gateway. Também fornecerei um repositório JavaScript GitHub funcional para que você possa brincar com ele.
Índice
O que é um WebSocket?
WebSocket é um protocolo de comunicação de computador , que fornece um canal de comunicação bidirecional simultâneo por meio de uma única conexão de Protocolo de Controle de Transmissão (TCP) - Wikipedia
Web sockets não são nenhuma novidade. Eles são usados em todos os aplicativos sociais no seu telefone e em vários sites que mostram placares ao vivo e atualizações em tempo real. Você já se perguntou como sua aba do Chrome é magicamente atualizada com novas informações? Não, não é uma pesquisa. São WebSockets. O backend do aplicativo envia uma atualização (transmissão/unicast/multicast) para o web socket do seu navegador.
Embora o protocolo tenha sua própria implementação sobre o TCP, ele inicia seu handshake sobre o protocolo HTTP e então "atualiza" para o protocolo WebSocket, onde ele faz suas próprias coisas de acordo com o RFC .
Se você quiser saber mais sobre o protocolo, confira o vídeo abaixo:
Vamos passar para os eventos do AppSync.
O que é o AppSync Events?
O AWS AppSync Events permite que você crie APIs WebSocket sem servidor seguras e de alto desempenho que podem transmitir dados de eventos em tempo real para milhões de assinantes, sem que você precise gerenciar conexões ou dimensionamento de recursos. - AWS
Primeiro, vamos deixar isso claro. Isso não tem nada a ver com GraphQL e AppSync.
É apenas uma má publicidade para essa nova interpretação de websockets sem servidor.
Conceitos e terminologia básicos
Os eventos do AppSync são interpretados de forma diferente em WebSockets, tanto no nível do protocolo físico quanto no gerenciamento sem servidor e na interpretação de mensagens.
No meu entendimento, de acordo com a documentação , eles adicionaram outra camada de abstração, um subprotocolo interno (AppSync-y) para gerenciar uma nova entidade de canal em cima de um único WebSocket. Isso pode ser visto no diagrama do guia do desenvolvedor da AWS :
Depois que os clientes se conectam ao ponto de extremidade do AppSync, eles podem tentar assinar um canal .
O truque legal aqui é conectar-se a vários canais no mesmo web socket. Isso dá a ilusão de vários tópicos/canais " pub-sub ", mas é tudo o mesmo web socket abstrato por baixo. Belo toque!
A assinatura requer autorização e há cinco opções:
Essas opções cobrem todos os métodos de autorização padrão . Eu geralmente opto por uma função Lambda que verifica o cookie seguro do aplicativo da web e o JWT e verificações adicionais.
A documentação entra em muitos detalhes e até fornece um exemplo de esquema de entrada de função Lambda e uma implementação de amostra - impressionante!
Voltando ao tópico de canais, há o canal / default , mas você pode adicionar mais canais. Um namespace de canal é composto de no máximo cinco segmentos, oferecendo um alto grau de flexibilidade. Pense nisso como subtópicos de pub orientados à IU.
Por exemplo, você pode criar um canal para atualizações gerais de usuários, ou por categorias como NBA, Futebol, e assim por diante. A capacidade de usar até cinco segmentos lhe dá o poder de publicar atualizações sobre diferentes esportes: como /users/nba e /users/football .
Além disso, você pode assinar /users/nba/ para receber notícias gerais da NBA, ou assinar /users/nba/* (curinga!), o que significa que você recebe todas as notícias da NBA de subsegmentos como /users/nba/bulls e /users/nba/lakers.
Quando se trata de publicação, isso pode ser feito tanto do frontend quanto do backend e requer autorização. Você pode definir um método de autorização diferente por canal e usar uma função Lambda (um toque legal!). Se você tiver permissão para publicar mensagens nesses canais, você só precisa enviar uma solicitação HTTP para o endereço do canal (e dos segmentos). Você pode publicar de uma função Lambda ou Event Bridge ( destino da API , eu presumo) transformando AppSync Events em um habilitador de arquitetura orientado a eventos.
Primeiras impressões e uso
Eu segui o console e a documentação e criei minha primeira API de Eventos. Não me lembro da última vez que vi uma documentação tão bem feita para um novo lançamento. Há suporte para muitos autorizadores e até mesmo exemplos de código para o lado do cliente. Um recurso gritante que está faltando é o suporte ao CDK, que é apenas um L1. No momento em que escrevo, há um problema aberto para o CDK L2. Comecei com o básico - a autorização de chave de API não muito segura.
Não usei o pub/sub-editor do consoler. Fui direto para brincar com um aplicativo da web e tentei assinar e publicar em um canal. Usei os exemplos de código do console. E funcionou.
Tive alguns pequenos problemas porque sou um completo novato em frontend, mas depois de alguma ajuda do meu incrível colega Afik Grinstein , tivemos um projeto Vite funcional .
O repositório completo do GitHub pode ser encontrado em https://github.com/ran-isenberg/appsync-events-client .
Vamos rever o que construímos:
Nosso cliente assina o canal e o segmento 'default/test'. Uma vez inscrito, ele publica eventos por meio da seção de entrada de texto da UI de publicação.
A seção de logs de eventos exibe todas as mensagens publicadas em '/default/test'.
e sim, é realmente um websocket com protocolo AppSync dentro:
e:
Aqui está o código JS, bem simples ao usar o Amplify SDK:
Consegui assinar outro canal, por exemplo, '/users', e verificar a assinatura curinga. Sim, funciona e é super fácil. Ao lidar com canais unicast ou específicos do cliente, você deve adicionar autorização personalizada para verificar se o usuário pode assinar essa mensagem de ID de usuário/inquilino.
De qualquer forma, honestamente, isso é impressionante, simplesmente funciona.
Se você estiver interessado no código completo e no arquivo HTML, eles estão aqui .
Vamos para a seção de insights, onde as coisas ficam picantes.
Insights e dicas
Nesta seção, compartilharei alguns insights obtidos ao usar o serviço por várias horas, levando ao resumo e à conclusão: vou usá-lo ou não?
Segurança
Gosto da flexibilidade das opções de autorização. Cinco tipos de autorização para a conexão inicial e autorização extra para assinaturas específicas do canal são mais do que suficientes.
Você também pode adicionar um método de autorização de conexão por canal e ajustá-lo para solicitações de publicação e assinatura com um Lambda de sua escolha. Aqui está um exemplo de manipulador .
Há suporte para AWS WAF, que não existe para API Gateway Websockets. É obrigatório, pois estamos expondo um endpoint HTTP para publicar mensagens.
Confira minha postagem no blog aqui para saber mais sobre o AWS WAF.
Sem tabelas de conexão
Não há necessidade de gerenciar tabelas de conexão; é genuinamente sem servidor!
Se você não tem ideia do porquê estou surpreso, é porque ao usar API Gateway WebSockets - quando você quer enviar uma mensagem para um usuário, você precisa saber o ID de conexão do web socket. Esse mapeamento é visível durante o processo de handshake ($connect) quando você autentica o usuário e permite a conexão, o que significa que você precisa salvá-lo em algum lugar para seu serviço de backend. O DynamoDB é uma excelente opção para armazenar essas informações de chave-valor, mas é um código que você precisa adicionar, escrever, manter e testar. Não é grande coisa, mas a AWS não nos deu isso pronto para uso. Aqui está ele resumido. Você não sabe o ID de conexão (e tenho certeza de que há um); você fala as línguas dos canais. Você nem sabe quem está conectado aos canais; a suposição aqui é que você nem se importa. Você quer publicar uma mensagem em um canal, e quem estiver inscrito receberá essa mensagem. Pub-sub clássico.
Para resumir, é uma abordagem diferente: canal vs. ID de conexão.
Transmissão em massa é fácil
Com sockets do API Gateway, você precisa iterar a tabela de conexão, buscar os IDs de conexão relevantes e, em seguida, usar o AWS SDK para publicar uma mensagem. Você precisa lidar com erros, novas tentativas, limitação, e fica muito desafiador quando a lista de público-alvo fica maior.
Com o AppSync Events, tudo o que você precisa fazer é fazer UMA chamada de API para um endpoint HTTP com a autorização correta — alucinante. Simples .
No entanto, você não tem nenhum feedback sobre quais usuários receberam ou não a mensagem. Com os web sockets do API GW, se você publicar em um ID de conexão fechado, você obtém uma exceção e sabe disso. Talvez isso não seja importante para seu caso de uso, mas você deve estar ciente disso.
Prezada equipe do AppSync Events, Tenho uma sugestão. E se pudesse haver um recurso de fila de mensagens para canais? Um recurso em que canais específicos (/users) armazenam dados por um tempo predefinido, mesmo que os usuários façam logout. Então, quando a assinatura do canal for restaurada (/users/
O isolamento do inquilino/usuário requer um design de canal
Unicast é mais difícil (mais ou menos, mas não muito). Digamos que eu precise enviar mensagens específicas do usuário pelo websocket e todas as mensagens gerais dos clientes, mas elas são específicas do cliente e não podem ser enviadas para todos.
Nosso namespace de canais pode ser parecido com isto: usuários assinam '/tenant/
Esteja avisado: Os namespaces de canais não são infinitos. Há uma cota de 50, mas é um link suave.
Além disso, cada namespace tem uma limitação de 50 caracteres, então preste atenção ao adicionar IDs de locatário ou IDs de usuário à peça: um UUID padrão tem 36 caracteres.
(Excesso de) flexibilidade significa complexidade
Projetar canais e autorizar usuários para canais adiciona complexidade. Você precisa entender como modelá-los; lembre-se de que tipo de dados (pessoais ou não) vão para onde, porque não há proteção aqui. Você precisa construí-los. Você precisa construir a lógica em sua autorização de canal personalizada. Você também precisa garantir que seus clientes front-end assinem os canais corretos. Além disso, quanto mais entidades você adicionar ao sistema, mais alterações de código precisará fazer - se você adicionar uma persona 'admin', poderá precisar adicionar um novo namespace ou assinatura diferente/extra com todos os seus manipuladores de autorização atualizados.
É muito mais complicado do que na API GW WebSockets, onde você se conecta e escuta mensagens. Claro, preciso construir uma tabela DynamoDB que mantenha um mapeamento entre o ID de conexão, o ID do usuário e o ID da sessão, mas isso é bem básico.
Experiência do desenvolvedor
A documentação é boa, mas não perfeita. O suporte ao CDK é severamente faltando .
O subeditor pub é um toque legal para testes rápidos de um canal e sua autorização. Não espero que os desenvolvedores de backend trabalhem no console diariamente, no entanto. É uma boa opção para desenvolvedores que querem testar um novo canal e ver dados de seu publicador de backend.
Os exemplos de código do Amplify são bons, me fizeram começar muito rápido. Se você não usa o SDK deles, ainda pode usar a API de Eventos, mas precisará adicionar todos os cabeçalhos do AppSync nos lugares corretos.
Por fim, você tem que usar o manipulador de eventos JavaScript integrado para os manipuladores de canais personalizados ' onSubscribe' e 'onPublish'. Você não pode trazer sua própria função ou dependências. Não é a melhor experiência na minha opinião.
Preços
Como Jeremy Daly mencionou :
o preço é 3x mais barato que o API Gateway WebSockets para minutos de conexão. US$ 0,08 por milhão de minutos de conexão para AppSync versus US$ 0,25 por milhão para API Gateway. As transferências de mensagens parecem ser as mesmas, mas o AppSync parece cobrar por cada "operação".
Há também uma generosa camada gratuita.
Na minha opinião, isso é uma vitória do AppSync em relação ao API Gateway.
Resumo - Bem feito ou apenas diferente - Ou em outras palavras, eu usarei?
AppSync Events é uma nova abordagem para Serverless WebSockets. Ele adiciona complexidade à autorização e ao gerenciamento de canais, mas corrige a principal desvantagem de usar Api GW web sockets para transmissão em massa.
Se você não precisa de transmissão em massa e sempre envia mensagens específicas do usuário, os websockets regulares da API GW são uma opção sólida e testada em batalha. Escreverei um post de blog sobre isso em breve com exemplos de código CDK também!
O serviço tem um futuro brilhante e muito potencial. Eu o recomendo fortemente para POCs, startups e outras empresas que estejam dispostas a serem early adopters.
No entanto, como arquiteto corporativo, devo pensar cuidadosamente sobre isso. A experiência do desenvolvedor não é ótima, o gov-cloud ainda não é suportado e ser um adotante inicial significa que o serviço pode quebrar ou mudar do nada. Além disso, a julgar pelo passado, por exemplo, Evidently e AppConfig pareciam fazer o mesmo conjunto de recursos, mas com algumas diferenças, e no final, AppConfig permaneceu, e Evidently não . A propósito, se você quiser saber mais sobre AppConfig para sinalizadores de recursos, confira minha postagem aqui .
Mas quem sabe, talvez seja o contrário. Talvez os web sockets do API Gateway sejam descontinuados com o tempo. Tudo depende da adoção do AppSync Events e da melhoria da experiência do desenvolvedor e da documentação pela equipe de serviço.