Guida alla Certificazione AWS Solutions Architect - Associate | 1/2
Quando si vuole dare un boost alla propria carriera potrebbe essere utile puntare l’attenzione...
In questo articolo vogliamo approfondire le differenze tra due diverse tecniche di comunicazione a livello applicativo: REST e WebSocket.
Il problema a cui si vuole trovare una soluzione, possibilmente la migliore possibile, è quello di scambiare dati tra il lato server e quello client all'interno di un contesto applicativo.
Questa problematica è presente nei contesti di uso comune come le applicazioni web oltre alle applicazioni classiche, in quanto hanno sempre la necessità di scambiare dati e comandi con il proprio server – dati sui quali si basa la GUI dell'app dal punto di vista del contenuto, ma anche delle funzionalità.
Pensiamo ad esempio a una dashboard di un applicativo: esso dovrà ottenere i dati da mostrare attraverso una chiamata a un server e potrebbe fare delle operazioni su di esso attraverso altre chiamate al server stesso.
Storicamente tale problema è stato affrontato con la tecnica REST sfruttando il protocollo HTTP. Successivamente nel tempo è nato un nuovo protocollo di comunicazione che fa riferimento ad altri paradigmi: le API WebSocket.
Procediamo per gradi e analizziamo le due soluzioni.
REpresentational State Transfer, questo è il nome da cui ha origine l'acronimo REST.
Con questo termine si identifica uno stile architetturale per la costruzione di interfacce di programmazione delle applicazioni (API).
Tale architettura ha alcuni punti cardine:
Un esempio di endpoint REST potrebbe essere:
GET https://server.domain.com:8080/resource/path/
Da questo endpoint ci si aspetta ricevere informazioni sulla risorsa descritta dal path.
Sicuramente la semplicità dell'architettura è un vantaggio: è sempre molto chiaro chi fornisce i dati e chi li usa una volta definito il metodo HTTP che stiamo usando.
Comodo inoltre perché permette un livello di astrazione molto alto grazie agli standard: posso decidere di far dialogare due servizi molto diversi tra loro senza preoccuparmi di come verrà implementata la gestione dall'altro lato.
Sincronicità: ogni chiamata tipicamente attende la risposta. Nel modello standard il concetto è: necessito di un dato, lo chiedo, attendo la risposta, elaboro il dato.
Questo modello è molto lineare, ma a volte è limitante: ad esempio va benissimo per sapere l'ultima volta che un utente si è loggato, ma se volessimo sapere quando un utente si logga dovremmo fare polling andando a chiedere ogni tot secondi se l'utente è loggato oppure no.
Oppure se un'operazione server-side richiede più di 60 secondi, la richiesta REST va in timeout e deve anch'essa essere convertita in una richiesta multipla, una per l'attivazione del servizio e una o più per la verifica della disponibilità del servizio.
Questa è una tecnologia web che fornisce un canale bidirezionale tra due dispositivi, tipicamente anche in questo caso un client e un server. La possibilità di inviare messaggi in entrambe le direzioni a piacimento senza bisogno di interazione da parte dell'interlocutore apre molte possibilità per un'architettura più leggera e snella.
Tale protocollo non si basa su HTTP: anzi, lo va a sostituire nella chiamata al server instaurando un canale nel quale sia il client che il server possono scrivere messaggi testuali indipendentemente l'uno dall'altro.
Dopo una prima fase di handshake dove i browser cambiano il protocollo da HTTP a WebSocket e si apre quindi il canale di comunicazione bidirezionale attraverso il quale possono essere scambiati dati.
Una differenza importante rispetto alle REST è la presenza di uno stato: l'esempio più emblematico è la fase di apertura in cui viene gestita l'autenticazione che viene successivamente mantenuta per tutta la durata degli scambi di messaggi tra le due parti senza necessità di ulteriori verifiche; inoltre il canale di comunicazione ha associato un identificativo al quale è possibile associare ulteriori dati mantenuti nello "stato" ed accessibili per tutta la durata della comunicazione.
Immaginiamo il caso che era critico per le API REST: vogliamo sapere quando un utente è loggato. In questo caso, basterà avere un WebSocket aperto e il server potrà notificarci quando il dato che vogliamo sarà disponibile senza andare a fare polling da parte del client.
Un altro esempio, immaginiamo che si debba interrogare il server e che l'elaborazione richieda molto tempo: attraverso il WebSocket sarà sufficiente mandare un messaggio con i dati della richiesta e attendere di ricevere il messaggio della risposta evitando fastidiosi timeout o complicate logiche di polling non lineari nel tempo.
Un altro grosso vantaggio è lo stato che la connessione eredita, come nell'esempio dell'autenticazione visto poco sopra. In questo modo il protocollo è parecchio più efficiente in caso di scambio di una mole importante di messaggi. Questo lo rende perfetto per le chat o i giochi online dato l'elevato numero di interazioni e la necessità di avere una bassa latenza.
Un'altro tipo di applicazione di questo canale bidirezionale è l'implementazione di Dashboard di monitoraggio con aggiornamento in real-time; ogni variazione di parametro della dashboard viene notificato mediante un passaggio in push da parte del server che porterà ad un aggiornamento immediato del solo elemento modificato senza l'aggiornamento dell'intera interfaccia.
Sicuramente questa tecnologia semplifica molti aspetti ma ne complica altri: la gestione lato server è molto più complessa e in generale il canale di comunicazione necessita di tecniche per la riapertura automatica poiché potrebbe chiudersi a causa di problemi di rete.
E' una tecnologia relativamente recente rispetto al protocollo HTTP ma la sua affidabilità è ormai oggi molto alta.
API gateway è la risposta in entrambe i casi. Questo servizio di AWS ci permette di gestire API sia di tipo REST che di tipo WebSocket semplificando molto la gestione lato server.
Questo va ovviamente a favore della seconda tecnologia la quale ha tra i principali svantaggi la complessità del server, brillantemente risolta dal servizio di AWS.
Un ulteriore vantaggio è il contesto, ovvero la possibilità da parte di un authorizer di definire in fase di connessione un insieme di dati che saranno disponibili nella gestione di tutti i messaggi, in qualsivoglia modo saranno gestiti.
Anche lato REST, il servizio API gateway di AWS semplifica molto la gestione del server andando a gestire tutte le varie resource con i vari metodi, anche qui con la gestione di uno o più authorizer che possono essere condivisi tra i diversi metodi degli endpoint, ma attenzione: ogni chiamata invocherà l'esecuzione del proprio authorizer a meno di servizi di cache dell'auth che però non sempre possono essere usati.
Da sottolineare anche l'integrazione con Cognito, identity provider gestito da AWS, attraverso la quale si può usufruire di authorizer predefiniti.
Dal punto di vista di sicurezza c'è una sostanziale differenza tra i due approcci: REST, basandosi su HTTPS usa un canale di comunicazione criptato a livello di trasporto per cui il messaggio non può essere letto da altri soggetti che non siano mittente e destinatario. Questo rende sicura la comunicazione di per sè, non il dato prima e dopo di essa.
I WebSocket usano il protocollo applicativo WS-security che approccia diversamente il problema: invece che criptare il canale di comunicazione, cripta il messaggio stesso. In questo modo il vantaggio è che non ci sono complessità a livello di trasporto e inoltre il messaggio è sicuro fino alla sua destinazione e non solo durante il trasporto.
Interessante l'analogia fatta in questo articolo dedicato all'End-to-End security, nel quale si fa il paragone con un motociclista che deve andare dal punto A al punto B. Meglio andare nudi all'interno di un tunnel opaco sperando di non essere visti mentre si entra e si esce, o meglio vestirsi prima di uscire di casa? Non penso ci siano molti dubbi su cosa ognuno di noi farebbe!
Abbiamo fatto una rapida panoramica su queste due tecniche di interazione tra dispositivi, tipicamente client e server. Non c'è vincitore assoluto poiché dipende molto dalle necessità specifiche della vostra applicazione.
L'importante è comprendere la differenza di paradigma: una soluzione (REST) prevede chiamate corpose dove tutti i dati viaggiano tra richiesta e risposta e va bene per interazioni sporadiche, molto distanti nel tempo o con contesti molto particolari.
L'altra soluzione (WebSocket) è migliore nei casi in cui siano previsti molti messaggi, ravvicinati nel tempo, e con un contesto probabilmente simile.
Sta di fatto che questa seconda tecnica è molto più efficiente per tutti i casi in cui può essere applicata, e va preferita in tali scenari, per le altre casistiche si ripiega su una più classica soluzione REST.
Quando si vuole dare un boost alla propria carriera potrebbe essere utile puntare l’attenzione...
“Clean Architecture” è un paradigma di progettazione software che Robert C. Martin propose sul suo...
Dopo aver descritto nell'articolo precedente la struttura della certificazione AWS Solutions...