Microservices gateway
Nel 2019 iniziai a lavorare per un piccola startup bio-tech a Santa Monica (CA).
Eravamo solo sei persone, io eri l'unico a dover pensare all'infrastruttura tecnologica, e le cose da fare erano veramente tante:
- e-commerce
- blog
- area riservata per il cliente (per visualizzare i report del DNA)
- Software LIMS per il laboratorio
- sequenziamento del DNA
- software amministrativo per rilasci dei report, customer care, etc.
Bisognava progettare tutto da zero, e tutto doveva essere pronto per una crescita esponenziale. Avevamo, infatti, finanziatori molto importanti, che si aspettavano anche un ritorno di investimento straordinario.
La prima scelta coraggiosa fu il DBase, un'architettura deve riflettere anche l'organizzazione aziendale e al momento non avevamo neppure una persona in grado di gestire un DBase.
La scelta più ovvia ricadde su un'archittura a microservizi.
Infatti applicando a questa tecnica anche le basi dell'architettura esagonale sarebbe stato possibile arginare eventuali modifiche future, assolutamente necessarie considerando le ipotesi di crescita.
E per il front end? dovevo ragionare in due termini: massimizzazione delle risorse e capacità di crescere.
Ionic era la scelta migliore: si poteva sviluppare in reactjs, quindi in javascript, quindi con lo stesso linguaggio usato in backend. Era già pronto per Apple store e Google play, e ciò significava essere pronti per ogni scelta di marketing (aumentare il fatturato significa assecondare in ogni cosa il marketing)
Per l'e-commerce invece non avevo dubbi: Shopify.
Avrebbe garantito stabilità, semplicità d'uso e un blog integrato che funzionava perfettamente. Purtroppo, però, l'area riservata non poteva essere sufficiente per noi: dovevamo visualizzare dati medici, in particolare mappature del DNA e, ovviamente, shopify non era pronto a questo.
Ci serviva un'area riservata separata.
Nacque un'applicazione in Ionic con chiamate al service gateway principale e un sistema di autenticazione basato interamente JWT: avrebbe garantito la compatibilità futura su qualsiasi tipo di migrazione: AWS, azure, google, tutto insomma.
Il dbase dei clienti venne trasformato in un servizio collegato tramite un plugin apposito a shopify.
In questo modo il servizio di autorizzazione e autenticazione non avrebbe dipeso da un servizio ma da un API, in questo modo, per il principio dell'architettura esagonale, per cambiare dbase (anche completamente diverso) sarebbe stato possibile wrapparlo semplicemente dentro il servizio utenti
E il dbase appunto?
E'stata una scelta veramente coraggio ma che si è rivelata estremamente vincente: NeDB
NEDB è un dbase noSQL completamente scritto in javascript e basato su un semplice file di testo perfettamente leggibile (quasi) come un json.
Molti sarebbero inorriditi nell'usare un dbase decisamente non standard ma, non potevo fare tutto io, e nedb aveva un'interfaccia identica a MongoDB, quindi facilmente intercambiabile in futuro.
con un dbase così agile sarebbe stato possibile concentrarsi su altro e soprattutto incapsularlo perfettamente nei microservizi riducendo quindi il rischio di una futura migrazione dei dati.
Fu una scelta fantastica, una semplice aggiunta al progetto opensource mi permise di aggiungere un backup automatico giornaliero su AWS S3 eliminando completamente il rischio di perdita dati e per quattro anni nessuno si ricordò dell'esistenza di un dbase! Completamente trasparente
Creai il gateway da zero. Non perchè fossi pazzo ma perchè necessitavo di alcune caratteristiche peculiari che difficilmente avrei trovato in altri gateway.
Mi spiego meglio: sequenziare il DNA costa moltissimo in termini di computazione. usavamo decine di EC2 in contemporanea (circa un centinaio di DNA sequenziali al giorno fin dal primo anno), così tanto che era necessario ottimizzare il costo di tutto il resto.
Il gateway che creai usava nodejs ed esponeva i servizi tramite expressjs. sapevo che in futuro avremmo potuto avere esigenza di migrare su sistemi cloud, per questa ragione creari delle classi adapter da utilizzare per esporre i servizi.
Queste classi esponevano dei metodi molto semplici ma molto efficaci per ovviare a due problemi principali:
- creare velocemente nuovi servizi
- garantire una futura migrazione senza cambiare il codice
per creare un nuovo servizio CRUD già perfettamente integrato ad un dbase embedded era necessario scrivere 4 righe di codice!
4 righe per ottenere GET/POST/PUT/DELETE e salvare il tutto su db. perfetto per le mie esigenze di fare tutto di corsa (ero solo).
poi ho creato un adapter che mi permettesse di avere la stessa identica interfaccia di expressjs ma che in realtà faceva molto di più: riusciva a interpretare i servizi esposti in modo da creare al volo delle meta-informazioni.
a cosa mi sono service: per generare i file OpenAPI e quindi tutta la documentazione necessaria e ovviamente grazie ad openAPi avrei reso possibile la creazione di test unitari e di integrazione senza impazzire.
Sono estremamente felice dei risultati di questo mio progetto.
È nato come un software sviluppato esclusivamente da me, per poi evolversi attraverso un team di dodici sviluppatori e oggi essere parte di una compagnia fortune500, il tutto senza aver richiesto cambi archietetturali.
ogni variazione è stata morbida, indolore e soprattutto perfettamente in orario.
ammetto di essere orgoglioso del lavoro svolto.
ps: in 3 anni siamo passati da 6 a 50 persone in organico.