AppSync implements WebSocket… How?
By Alessia Gentile
AppSync è un servizio di Amazon Web Services (AWS) che permette di creare API risolvendo una serie di complessità collegate al mondo microservizi utilizzando GraphQL come linguaggio di interrogazione e permettendo la sincronizzazione offline. AppSync consente agli sviluppatori di creare API flessibili e scalabili aggregando dati provenienti da fonti diverse come database, web services, ecc. Infatti le principali caratteristiche di questo servizio sono:
- GraphQL API: AppSync utilizza GraphQL, un linguaggio di query per API che permette di richiedere solamente i dati necessari, ottimizzando l’efficienza delle richieste
- Integrazione con diverse fonti dati: AppSync può aggregare dati da più fonti come DynamoDB, RDS, Elasticsearch, Lambda e altri servizi AWS, fornendo un’unica interfaccia API.
- Aggiornamenti in tempo reale: Supporta aggiornamenti in tempo reale tramite WebSockets, consentendo alle applicazioni di ricevere dati aggiornati automaticamente senza dover fare richieste continue
- Sincronizzazione offline: Le applicazioni possono funzionare offline, e AppSync si occupa della sincronizzazione dei dati quando la connessione viene ripristinata
- Sicurezza: Fornisce integrazioni con AWS Identity and Access Management (IAM), Amazon Cognito e altri servizi per gestire l’autenticazione e l’autorizzazione in modo sicuro.
I principali vantaggi di AppSync sono:
- Efficienza nello sviluppo: riduce la complessità di creare API moderne, supportando l’integrazione di più fonti di dati in un’unica API GraphQL alleggerendo il lavoro dello sviluppatore
- User Experience migliorata: Consente di creare applicazioni più reattive e interattive, con dati in tempo reale e supporto offline
- Scalabilità: Essendo un servizio gestito da AWS, AppSync scala automaticamente per gestire un alto volume di richieste e dati
In questo articolo ci concentreremo in particolare sull’utilizzo da parte di AppSync di WebSocket per l’aggiornamento in tempo reale e come in Santagostino abbiamo sfruttato questa particolare caratteristica.
Cos’è una WebSocket e come funziona?
Una WebSocket è un protocollo di comunicazione che fornisce un canale bidirezionale (full-duplex) su una singola connessione TCP. Questo significa che una WebSocket permette una comunicazione continua tra un client (ad esempio, un browser) e un server senza la necessità di aprire nuove connessioni per ogni messaggio che deve essere scambiato.
WebSocket è un protocollo standard definito nella specifica RFC 6455. Fornisce un’interfaccia per la programmazione dell’accesso alla rete a livello di Trasporto nello stack TCP/IP permette una comunicazione interattiva tra il client e il server con bassa latenza e senza il sovraccarico tipico delle richieste HTTP.
Funzionamento di una WebSocket
- Handshake iniziale:
- Il client invia una richiesta HTTP al server per aggiornare la connessione a WebSocket. Questa richiesta include specifici header HTTP, tra cui
Upgrade: websocket
eConnection: Upgrade
.
Il parametro Sec-WebSocket-Key viene popolato dal client con una stringa casuale in base64 - Se il server supporta WebSocket e accetta l’aggiornamento, risponde con un codice di stato
101 Switching Protocols
e include header specifici nella risposta
Il parametro Sec-WebSocket-Accept conterrà l’hash della stringa casuale generata dal client
- Il client invia una richiesta HTTP al server per aggiornare la connessione a WebSocket. Questa richiesta include specifici header HTTP, tra cui
- Connessione aperta:
- Una volta stabilita la connessione, il canale è aperto e i dati possono essere inviati e ricevuti in entrambe le direzioni simultaneamente. Non ci sono più overhead legati all’instaurazione di nuove connessioni, come avviene con le richieste HTTP tradizionali
- Comunicazione bidirezionale:
- Sia il client che il server possono inviare messaggi in qualsiasi momento. Questa è una differenza fondamentale rispetto al modello di richiesta-risposta di HTTP, dove solo il client può iniziare la comunicazione.
- I messaggi WebSocket sono inviati in frame, che possono essere molto piccoli e portare solo la minima quantità di informazioni necessarie, riducendo così la latenza.
- Mantenimento della connessione:
- La connessione WebSocket rimane aperta finché il client o il server non decide di chiuderla. Vengono usati pacchetti “ping” e “pong” per mantenere viva la connessione e per rilevare eventuali interruzioni
- Chiusura della connessione:
- La connessione WebSocket può essere chiusa da uno dei due lati (client o server) tramite un semplice frame di chiusura. Una volta chiusa, la connessione non può più essere riutilizzata e, se necessario, deve essere riaperta tramite un nuovo handshake
Come AppSync utilizza le WebSocket?
AppSync utilizza WebSocket per implementare la funzionalità di sottoscrizione (subscription) in tempo reale. Le sottoscrizioni permettono ai client di ricevere aggiornamenti in tempo reale quando i dati cambiano in seguito a operazioni come inserimenti, modifiche o cancellazioni. Questa capacità di aggiornamento in tempo reale è consentita proprio grazie alla comunicazione tramite WebSocket.
Nello specifico:
- AppSync sfrutta le WebSocket per implementare le sottoscrizioni GraphQL. Quando un client si sottoscrive a un determinato evento o dato, AppSync mantiene una connessione WebSocket aperta con il client e quando il dato a cui il client si è sottoscritto cambia, il server invia automaticamente una notifica al client attraverso la connessione stabilita tramite WebSocket.
- AppSync utilizza il protocollo HTTP per le operazioni di query e mutazione, ovvero per inviare richieste e ottenere risposte standard quando la comunicazione in tempo reale non è necessaria.
L’utilizzo delle WebSocket in AppSync permette di gestire un gran numero di connessioni simultanee con un basso overhead, rendendo la soluzione scalabile ed efficiente, ideale per applicazioni con molti utenti che richiedono aggiornamenti in tempo reale.
Le principali caratteristiche di AppSync che abbiamo sfruttato in Santagostino e un esempio di caso d’uso
Proprio grazie alla sua scalabilità, efficienza e update in tempo reale AppSync si è rivelato essere un servizio fondamentale per la nostra architettura software.
In particolare abbiamo sfruttato:
- i Resolvers che ci hanno permesso di combinare più operazioni in un’unica richiesta rendendo il codice più snello e manutenibile
- il Caching per le query per ridurre il carico sui microservizi di backend dove possibile. La nostra scelta è ricaduta sul Caching per resolver per rendere più performanti le interrogazioni GraphQL che sfruttano i resolver.
Attivare il Caching completo delle richieste è sicuramente una scelta vantaggiosa se i dati richiesti non cambiano frequentemente (la cache viene refreshata circa ogni ora) - Update in tempo reale grazie alle WebSocket. La tecnologia fondamentale del nostro sistema di gestione code pazienti.
Il Caso d’uso: Queue Manager
Il nostro sistema di gestione code pazienti utilizza ampiamente il concetto di WebSocket implementato da AppSync, in che modo?
- i nostri pazienti prendono un numero ai totem collocati all’ingresso dei nostri centri con maggiore affluenza
- grazie ad AppSync il numero viene comunicato in tempo reale al Desk e visualizzato sui monitor in modo che il paziente possa sempre sapere se il suo numero è stato chiamato o se è ancora in coda
Questa caratteristica permette di avere un sistema custom reattivo e sempre aggiornato, progettato per consentire ai nostri Desk Officer di avere sempre la situazione dei numeri in gestione attendibile e aggiornata in tempo reale.
Conclusioni
Utilizzare Amazon AppSync per aggiornamenti in tempo reale rappresenta una soluzione potente e versatile per costruire applicazioni moderne che richiedono interattività immediata e reattività costante.
AppSync automatizza molti aspetti della gestione delle WebSocket, inclusa la riconnessione automatica e il mantenimento della connessione, riducendo il carico di manutenzione per gli sviluppatori.
Un occhio attento va sempre rivolto ai costi: come la maggior parte dei servizi AWS AppSync è un servizio basato su consumo, quindi i costi sono direttamente proporzionali al numero di richieste e connessioni mantenute. Rimane quindi importante monitorare e ottimizzare l’uso per avere sempre costi sostenibili.