Introduzione ai Micro Frontend

Esattamente come il termine Microservices Architecture indica l’approccio allo sviluppo di una singola applicazione come insieme di piccoli servizi indipendenti, così il termine Micro Frontend indica il modo di pensare ad una applicazione web come alla composizione di funzionalità raggruppate in componenti separati. In pratica, i Micro Frontend estendono i concetti dei microservizi al mondo del frontend web.

Se, da un lato, ci sono poche controversie quando parliamo di progettazione di servizi di backend (grazie anche alla molteplice letteratura che è possibile trovare online) dall’altro le cose si complicano quando dobbiamo utilizzare i microservizi come elementi costitutivi per una soluzione di frontend.

Questo perché agli utenti finali non interessa quanto siamo bravi a dividere il nostro backend in microservizi, ma quello che conta è quanto siamo bravi a integrarli in modo trasparente nel browser, per creare un’applicazione omogenea ed accattivante dal punto di vista della UserExperience (UX).

Quindi la domanda a cui proviamo a rispondere in questo articolo è: come è possibile creare un sito web coerente o una app mobile utilizzando decine di microservizi differenti?

Per rispondere a questa domanda è necessario ricordare quali sono gli approcci più comuni quando si sviluppa il frontend di un’applicazione web.

L’approccio “monolitico”

L’approccio “monolitico” rappresenta il modo più semplice per realizzare un’applicazione web ed è caratterizzato dallo sviluppo di un’applicazione intesa come una singola entità.

Un solo team di sviluppatori crea e gestisce un’intera applicazione e ha il compito di scrivere e manutenere tutto il codice: dal database fino al frontend.

Queste applicazioni monolitiche sono facili da implementare, poiché hanno una sola base di codice, e sono tipicamente raccolte in un unico progetto, ma hanno lo svantaggio di non essere scalabili. 

Infatti questo tipo di architettura si presta bene per applicazioni piccole o comunque poco soggette a cambiamenti, ma il discorso cambia quando ci troviamo a sviluppare applicazioni complesse che evolvono rapidamente.

In una grande azienda, con molti team di sviluppo, il singolo team di frontend potrebbe diventare il collo di bottiglia per lo sviluppo. Oltre a questo, può facilmente accadere che le applicazioni monolitiche crescano in modo imprevedibile e esponenziale sia in dimensioni che in complessità, il che rende difficile muoversi rapidamente sia in fase di sviluppo che in quella di test.

Un eventuale nuovo sviluppatore che entra nel team, ha bisogno di imparare il funzionamento dell’intera applicazione, indipendentemente da quello che deve sviluppare; inoltre ogni piccola modifica deve passare attraverso un test completo dell’intera applicazione prima di poter essere distribuita in produzione.

Per ultimo, ma per questo non meno importante, l’unico modo per poter scalare un’applicazione monolitica è quello di replicare l’intera applicazione con il conseguente aumento dei costi e delle risorse necessarie. 

L’approccio “multi-tier”: Frontend e Backend

Dato che gli svantaggi dell’approccio monolitico sono stati fin da subito evidenti, gli sviluppatori hanno iniziato ben presto ad applicare il principio della scomposizione creando applicazioni suddivise in strati logici.

Questo approccio, che prende il nome di multi-tier, consiste generalmente nello scomporre un’applicazione in uno strato di dati (Database), uno strato di logica business (Backend) ed infine di uno strato di presentazione (Frontend).

Tramite questa suddivisione è possibile far scalare solamente lo strato con il maggior carico. Infatti è possibile replicare il database in maniera del tutto indipendente dal resto dell’applicazione piuttosto che far scalare solamente lo strato della logica business in seguito ad un aumento del carico di lavoro.

Purtroppo, le applicazioni di questo tipo, se diventano troppo grandi, presentano gli stessi svantaggi delle applicazioni monolitiche, con la sola differenza che tutto il carico si sposta nello strato della business logic.

Questo modello però ha avuto il grande merito di far iniziare la tendenza al disaccoppiamento dei componenti.

L’approccio “a servizi”

Il passo successivo è stato quello di scomporre le applicazioni in base alle funzionalità di business. Una applicazione diventa così una sorta di collezione di servizi ridotti e autonomi.

Ad esempio in un e-commerce potremmo avere uno servizio User Service che si occupa della gestione dell’autenticazione, un Order Service per la gestione degli ordini e un Notification Service per la gestione delle notifiche via email. 

Con questo tipo di architettura si ottengono vantaggi in termini di scalabilità e in termini di una maggiore semplicità, dato che esistono servizi separati e quindi potenzialmente più piccoli e facili da gestire.

Nonostante questo approccio abbia fornito un notevole miglioramento nella costruzione di architetture più efficaci, nella pratica la scomposizione in servizi si è sempre applicata al solo backend delle applicazioni, facendo sì che il frontend sia rimasto sempre un unico blocco monolitico.

L’approccio Micro Frontend

Una classica architettura a microservizi è costituita da un insieme di servizi ridotti e autonomi in cui ogni servizio è indipendente e implementa una singola funzionalità di business.

L’approccio a microservizi tende quindi alla realizzazione di una singola applicazione composta da n servizi sviluppati e implementati in maniera indipendente, secondo il Single Responsibility Principle (SRP).

Nonostante il termine micro possa portare a confusione, dato che un servizio può essere anche complesso e di una certa dimensione, la cosa veramente importante è che ogni servizio deve poter essere sviluppato e distribuito in maniera indipendente dagli altri.

Inoltre ogni servizio è responsabile della persistenza dei propri dati, differendo dal modello tradizionale nel quale la persistenza dei dati viene gestita da un livello dati distinto.

Premesso questo è facile intuire l’idea alla base dell’approccio a Micro Frontend ovvero pensare ad una web application o ad una app mobile come alla composizione di funzionalità di “proprietà” di team indipendenti.

Ogni team ha una specifica area di attività o mission a cui è dedicata e specializzata. Questo porta ad avere team multifunzionali che implementano le proprie funzionalità in modalità end-to-end ovvero dal database fino all’interfaccia utente.

Con l’architettura a Micro Frontend, possiamo quindi suddividere l’intera applicazione in domini delle entità secondo l’approccio Domain Driven Design (DDD) e delegare la ownership di un intero dominio ad un singolo team che avrà il compito di progettare e implementare tutte le funzionalità necessarie a realizzare la mission.

In pratica si tratta di suddividere un’applicazione in tante applicazioni; ogni applicazione ha un suo preciso scopo, è realizzata con la tecnologia più opportuna ed implementa l’infrastruttura e tutte le logiche necessarie al raggiungimento dell’obiettivo.

Pensando all’e-commerce dell’esempio precedente ed applicando la scomposizione in Micro Frontend arriviamo ad ottenere i layout delle pagine come la composizione dei layout di applicazioni differenti.

L’immagine sottostante mostra un esempio di e-commerce pensato come l’integrazione di applicazioni separate, realizzate da team differenti con tecnologie differenti.

Infatti è stato utilizzato Angular.Js per la realizzazione della pagina prodotto, React.Js per la realizzazione delle logiche del carrello e Vue.Js per la realizzazione dell’elenco dei prodotti correlati.

La divisione in componenti sicuramente crea un ambiente più efficace per il build e il mantenimento di applicazioni altamente scalabili. I micro frontend si sviluppano e distribuiscono in modo indipendente sono più facili da mantenere, correggere e aggiornare, portando a funzionalità più agili per rispondere ai cambiamenti ambientali odierni. 

Tra i benefici dell’architettura a Micro Frontends troviamo quindi:

  • Sviluppi indipendenti: Ogni funzionalità è sviluppata e testata indipendentemente dalle altre funzionalità.
  • Alta scalabilità: La scalabilità dell’interno sistema è data dalla scalabilità di ogni singola applicazione e diventa più conveniente oltre che poter essere fatta on demand. 
  • Alta resilienza: la separazione in componenti di un’applicazione rende molto meno probabile che un bug o un problema si rifletta sull’intero sistema. Eventuali componenti “difettosi” possono essere isolati singolarmente, riparati e rimessi in funzione senza necessariamente interrompere le funzionalità dell’intera applicazione.
  • Iterazioni più veloci: Il codice risulta più semplice da capire per gli sviluppatori i quali si possono concentrare su compiti specifici senza impattare sul resto dell’applicazione e senza la necessità di doversi coordinare con gli altri programmatori.
  • Supporto di tecnologie differenti: Dato che ogni Micro Frontend è un’applicazione a sé stante è possibile far coesistere tra di loro applicazioni realizzate con tecnologie differenti come ad esempio Angular.Js, React.Js e Vue.Js

Naturalmente nessuna architettura è esule da svantaggi e in genere ogni architettura applicativa che tenta di risolvere i problemi di scalabilità si trova a dover affrontare i problemi legati alla complessa natura dei sistemi distribuiti.

Tra gli svantaggi abbiamo:

  • Orchestrazione più complessa: avere più applicazioni significa anche gestire più flussi di distribuzione cha vanno mantenuti corretti e coerenti per tutto il ciclo di vita dell’applicazione.
  • Coerenza dei dati: garantire la coerenza dei dati è una sfida, sia per lo store dei dati che per i dati in transito sulla rete. Più database e lo scambio costante di informazioni possono facilmente portare a incoerenze se i domini delle applicazioni non sono ben progettati.
  • Controllo delle versioni: gli aggiornamenti a un servizio non devono interrompere i servizi che dipendono da esso. Potrebbero essere aggiornati più servizi in un dato momento, pertanto senza un’attenta progettazione si potrebbero verificare problemi di compatibilità con le versioni precedenti o successive.
  • Mancanza di governance: potrebbero esserci così tanti linguaggi e framework diversi che l’applicazione diventa difficile da gestire. Può essere utile applicare alcuni standard a livello di progetto, senza limitare eccessivamente la flessibilità dei team. Questo vale in special modo per le funzionalità trasversali come ad esempio la registrazione al sistema oppure l’utilizzo dei fogli di stile.

Rispondendo dunque alla domanda iniziale è possibile creare un’applicazione coerente che sfrutta decine di microservizi adottando l’approccio a Micro Frontend tenendo presente però che è necessaria una strategia ben definita per mettere in campo un’applicazione che risulta essere data dalla composizione di tante applicazioni più piccole.

Infatti se da un lato ci sono molte ottime ragioni per adottare un’architettura di questo tipo (scalabilità, resilienza, hardware e software dedicato ecc..) è pur vero che è introdotta molta complessità nell’ecosistema del frontend.

In genere prima di rivoluzionare una app per utilizzare i Micro Frontend è necessario assicurarsi di:

  • Avere un’applicazione altamente complessa: è probabile che la maggior parte degli sviluppatori non lavori in aziende abbastanza grandi da garantire team differenti per ogni Micro Frontend. I micro frontend iniziano davvero a brillare quando il frontend diventata così grande che nessun team può capire come funziona l’intera cosa (figuriamoci una singola persona).
  • Avere più team ognuno con i propri cicli di distribuzione: il fatto di separare un’applicazione più grande in più Micro Frontend consente a ogni team di distribuire la propria parte del prodotto senza interferire con i cicli di rilascio del resto dell’organizzazione.

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *