Negli ultimi giorni abbiamo rilasciato un aggiornamento della nostra app Casualis:
La novità principale inclusa in questo aggiornamento è una nuova funzionalità chiamata “Sfondo del giorno“. Grazie a questa nuova funzionalità gli utenti riceveranno ogni giorno una notifica con uno sfondo nuovo, ma attenzione: lo sfondo del giorno non è presente in nessuna collezione o raccolta, l’unico modo per ottenerlo è aprire la notifica o, in un secondo momento, utilizzare la nuova voce di menu.
Nella notifica abbiamo incluso una immagine che lascia intravedere una anteprima dello sfondo del giorno, per invogliare gli utenti ad aprire la notifica stessa.
Tutto questo è stato implementato utilizzando Firebase. La scelta si è basata sul fatto che Casualis utilizza già molte funzionalità di Firebase, e stavo solo aspettando l’occasione per chiudere il cerchio e provare le poche funzionalità che ancora non avevo testato.
Ma partiamo dal principio: perché sviluppare questa nuova funzionalità serverless, e più nello specifico, tramite microservices? Perché una delle nostre altre app (Do It!), implementa una funzionalità molto simile allo sfondo del giorno, ed è stata sviluppata con un approccio più classico, ovvero realizzando una web app con Laravel. Da qui l’idea di cogliere l’occasione e provare a implementare una funzionalità similare utilizzando però un approccio completamente diverso, con l’obiettivo di poter poi confrontare eventuali pro e contro di queste due soluzioni agli antipodi.
Entriamo un po’ più nel dettaglio dell’implementazione con uno schema riassuntivo del funzionamento dello sfondo del giorno:
Il funzionamento nel dettaglio quindi è:
- Periodicamente tramite una CLI realizzata in NodeJs, vengono importati nel database alcuni sfondi, li chiameremo sfondi del giorno “next”
- Una volta al giorno viene eseguita automaticamente una cloud function che:
- sceglie uno degli sfondi importati in precedenza
- crea la thumbnail da mostrare nella notifica e la salva nel cloud storage
- crea e invia le notifiche in diverse lingue
- salva nel database le informazioni dello sfondo del giorno appena creato
- esegue il cleanup delle thumbnail obsolete presenti nel cloud storage
- Quando l’utente preme sulla nuova voce di menu “Sfondo del giorno”, l’app invoca un endpoint gestito sempre tramite cloud function per ottenere le informazioni sullo sfondo del giorno.
- A corredo di tutto ciò ci sono due cloud function eseguite in corrispondenza dell’aggiunta o rimozione degli sfondo del giorno “next”: l’obiettivo è quello di tenere aggiornato un contatore degli sfondi (ebbene sì, non è così semplice fare un count su Firestore) e, soprattutto, inviare degli alert quando gli sfondi del giorno “next” sono pochi ed è necessario quindi importarne di nuovi.
Uno degli aspetti più positivi di questa implementazione è il monitoring: in una applicazione web classica questo punto spesso lascia un po’ a desiderare, a meno di non integrare servizi esterni. Qui non solo è possibile eseguire query avanzate sui dati di logging, ma è possibile anche impostare degli alert (via mail ma non solo) al verificarsi di determinate condizioni: abbiamo usato questo strumento anche per ricevere i warning relativi agli sfondi del giorno “next” in esaurimento di cui abbiamo parlato poco fa.
Uno degli aspetti più critici invece è sicuramente il vendor lock-in: si ha davvero la sensazione di scrivere del codice che è strettamente legato allo stack offerto dal cloud provider scelto, e quindi poco portabile. Un altro aspetto molto lacunoso è la possibilità di testing e di emulazione in locale: Firebase offre l’emulazione in locale di alcune funzionalità, ma non penso sia ancora sufficiente.
Questa implementazione è stata però sicuramente più rapida di quella realizzata con Laravel per Do It!, ed è anche sicuramente molto più scalabile, fattore che con circa 10K utenti attivi va tenuto in considerazione, soprattutto considerando che la notifica viene inviata in contemporanea a tutti gli utenti, causando quindi un picco di traffico importante concentrato in pochi minuti.
Da un punto di vista della manutenibilità e evoluzione sono sinceramente combattuto su quale soluzione possa offrire i vantaggi maggiori: da un lato l’applicazione monolitica offre un maggior grado di coesione e di uniformità, nonché di testabilità e portabilità, dall’altro l’architettura serveless a microservizi permette di suddividere l’app in moduli comunicanti ma indipendenti sotto ogni aspetto, sviluppati potenzialmente anche con linguaggi e tecnologie diverse tra loro.
Insomma, lo sappiamo, di silver bullet non ne esistono, e anche con questa esperienza ne ho avuto la riprova, ma questo non deve dissuaderci dal guardare con curiosità a tutte le nuove tecnologie che nascono (praticamente) ogni giorno per coglierne il potenziale e ampliare le nostre conoscenze.