Aprile 21, 2020 - Commenti disabilitati su Perché è importante uno sviluppo iterativo e incrementale anche in una libreria OpenSource?
Perché è importante uno sviluppo iterativo e incrementale anche in una libreria OpenSource?
Questa è la nostra esperienza sulla realizzazione di una libreria OpenSource, di come lo sviluppo iterativo, incrementale si applichi non solo a progetti "commerciali" ma anche allo sviluppo open source, in particolare a quello guidato dalle esigenze e dal feedback.
Questa è la storia di Daikon
a dead simple and minimal framework for creating web applications in Kotlin with minimal effort
Una libreria utiizzata in molti progetti del nostro team.
La Nascita
Tutto è nato dal team in cui lavoriamo: il Team Vega e dal nostro coinvolgimento su progetti riguardanti lo sviluppo di applicazioni web in Kotlin.
Siamo stati per molto tempo dei fan di SparkJava per la sua semplicità e il suo DSL molto intuitivo.
Un'applicazione scritta in Spark è anche abbastanza semplice da testare e da manutenere, ma ci trovavamo spesso nelle condizioni di non poter usare SparkJava anche per i test.
In particolare, come spesso accade, abbiamo a che fare con servizi esterni (autenticazione, API varie, etc...), quindi nei test E2E ci piace (ove non sono disponibili i servizi veri) usare delle implementazioni che simulano il comportamento reale. Per fare questo solitamente creiamo dei test che lanciano delle API HTTP programmabili con validazioni e risposte realistiche.
Con SparkJava non possiamo lanciare più di un server HTTP nella stessa applicazione, questo perché dietro le quinte lavora con oggetti statici.
Sappiamo però che esistono librerie per soddisfare questa necessità ad esempio WireMock, ma non ci siamo mai trovati troppo bene ed in più ci forzano a configurare API HTTP in due modi diversi:
1. la libreria per il codice di produzione
2. la libreria per il codice di test.
Questo è stato uno dei motivi che hanno dato il via allo sviluppo di Daikon: avere un unico modo per lanciare più applicazioni che usano HTTP nella stessa suite di test.
In più volevamo anche qualcosa che fosse:
- rapido a partire e a servire richieste, dato che ultimamente stiamo lavorando parecchio su container docker che per loro natura sono volatili e necessitano di startup veloci.
- senza magia, ovvero la possibilità di capire facilmente come utilizzare la libreria senza magie/convenzioni che obblighino gli utilizzatori a fare mille ricerche su StackOverflow. (es: SpringBoot)
L'Evoluzione
Cosa sta dietro al concetto di iterativo-incrementale in pratica?
L'idea parte dalla necessità di trovare un modo per validare il prima possibile quello che stiamo sviluppando e capire se questo porta valore.
Per andare in questa direzione dobbiamo avere sempre qualcosa di funzionante e pronto per essere utilizzato anche se con funzionalità ridotte, grezze e migliorabili.
Non solo, gli incrementi e le raffinazioni devono essere guidate dal feedback e motivate da reali esigenze, senza speculare su quello che potrà essere o potrà avvenire nel futuro.
Oramai è qualcosa che noi in Claranet Italia diamo per scontato nella realizzazione dei progetti, ma non sempre è un concetto che viene applicato da chi sviluppa, in modo particolare nel mondo OpenSource.
A volte perché si sviluppa pensando a utilizzatori immaginari (non reali), a volte perché ci si fa prendere da manie di grandezza con il risultato di complicare il codice provando a renderlo più estensibile/configurabile/astratto, salvo poi ritrovarsi tra le mani un codice più complesso e difficile da manutenere senza una reale necessità.
In Daikon tutto (o quasi) è stato guidato dal feedback e dalla necessità.
Le prime versioni erano molto scarne: si faceva partire un' applicazione web con pochi metodi HTTP supportati, solo GET, POST e poco altro.
Man mano che usavamo Daikon nei nostri progetti, ci rendevamo conto che mancavano delle funzionalità. Quindi cercavamo di utilizzare queste reali necessità come spinta alla crescita di Daikon invece che svilupparle all'interno dei singoli progetti.
Siccome non siamo soli nell'universo, anche i feedback di colleghi, clienti e collaboratori sono stati importantissimi per capire quali funzionalità aggiungere o affinare.
Nonostante avessimo testato l'applicazione con scrupolo e il suo design sia stato fatto in TDD, niente è esente da bug. Questi feedback, quindi, ci hanno aiutato molto a trovarne alcuni (pochi per fortuna), verificarli con dei test e correggerli.
Man mano che Daikon veniva usato ci sono stati segnalati alcuni miglioramenti che avrebbero potuto semplificare il suo utilizzo e così, basandoci su necessità, feedback e uso quotidiano, abbiamo fatto la sua roadmap, fino a renderlo una libreria stabile e usata in diversi progetti in produzione.
I Traguardi Raggiunti
Uno degli obiettivi che ci eravamo prefissati era di tenere la libreria il più snella possibile. Per questo motivo abbiamo sempre cercato di evitare l'aggiunta di dipendenze. Quando qualcosa si rendeva necessario (es: parsing delle richieste e risposte in JSON) creavamo delle estensioni per Daikon che a tutti gli effetti erano progetti separati.
In questo modo l'utilizzatore ha a disposizione il set minimo di funzionalità che gli servono ed eventualmente aggiunge le estensioni alla sue dipendenze per le altre funzionalità.
Per quanto riguarda le estensioni, ci è venuto in soccorso Kotlin che, grazie alle Extension Functions, ci ha permesso di trovare un modo elegante, leggero ed espressivo per estendere il core di Daikon.
Sono nate così diverse estensioni:
* Daikon Freemarker
* Daikon Gson
* Daikon Jackson XML
* Daikon Eureka
* Daikon Prometheus
Dopo qualche tempo abbiamo iniziato a gestire anche alcuni servizi Serverless, quindi abbiamo deciso di estrarre l'intero routing nel CORE di Daikon in modo che fosse flessibile ed utilizzabile sia come server HTTP (usando Jetty) sia in Lambda che semplifica la gestione di applicazioni serverless.
Quindi è nato un altro interessante progettino: Daikon Lambda che ha la stessa interfaccia e le stesse funzionalità di base di Daikon.
Abbiamo poi deciso di estendere il concetto di semplicità e minimalismo anche al client HTTP. Così è nato anche Topinambur.
Collaborazione ed entusiasmo
Una cosa che ci è piaciuta moltissimo è stato il fatto che il Team Vega non fosse solo in questa avventura. Ai nostri colleghi è piaciuto il progetto e si sono adoperati per darci una mano a realizzare qualcosa che mancava o a migliorare quanto avevamo fatto. Ad esempio Daikon Prometheus è nato dall'esperienza in quell'ambito di un nostro collega che ha visto l'opportunità di estendere la nostra libreria con quanto conosceva.
I clienti, inoltre, si sono dimostrati da subito entusiasti del progetto, sia perché avevano a disposizione qualcosa di funzionante e semplice integrato nei loro progetti, sia perché lo hanno potuto integrare in altri loro sistemi senza difficoltà e molto velocemente. Senza contare il fatto che lo sviluppo di Daikon non aveva intaccato (se non positivamente ) la delivery del progetto.
Feedback
Daikon è un progetto in continua crescita che si evolverà ulteriormente grazie ai feedback che riceveremo. Potete contribuire in vari modi:
* usatelo e diteci come vi trovate, cosa vorreste avere in più o cosa vorreste migliorare;
* diventate contributor del progetto;
* mettete un like a questo post e una stellina al progetto su GitHub.
PS: vi siete chiesti come mai le librerie hanno nomi di vegetali? Basta nomi di animali, finalmente una libreria vegetariana!