AngularJS, Angular, Express, Spring, JavaScript, TypeScript, Java, FronEnd, BackEnd… Framework e linguaggi diversi che condividono le stesse problematiche di sviluppo; negli anni ho sempre seguito concetti come la centralizzazione del codice, l’atomicità dei componenti/classi, la riusabilità e l’estensibilità degli stessi, finendo per iniziare ogni nuovo progetto da quelle che definisco “le fondamenta”: una serie di utility che permettono di sviluppare più rapidamente e risolvere problematiche comuni a diverse funzionalità, pagine o servizi, agendo in un unico punto e seguendo un filo logico intuitivo favorendo eventuali passaggi di consegne.
Spesso si inizia un progetto senza avere una visione chiara del prodotto finale o quello che si andrà a fare a livello tecnico: uno degli errori più grandi è procedere senza uno schema iniziale; è infatti indispensabile da subito dedicare utility, funzioni wrapper, file di configurazione e costanti.
Configurazioni: Costanti, Enumeratori
Anche se apparentemente banale, dedicare file specifici per set di stringhe, valori, parametri di configurazione ed espressioni regolari, è di vitale importanza per avere da subito un insieme specifico di file dedicati per contenere valori frequentemente utilizzati nel progetto; di seguito qualche esempio concettuale:
- Criteri di validazione
- Espressioni regolari
- lunghezza minima e massima stringa
- valore minimo e massimo numerico
- Parametri di configurazione web/client
- Timeout (utili per simulare timeout di produzione inferiori ai 120 secondi dei browser)
- Eventuali header da iniettare in ogni chiamata
- Output (nel caso non provengano da un db)
- Testi per l’utente / localizzazione
- Errori / Codici di errore
Utility
Anche realizzare utility per le operazioni più banali è spesso una pratica molto sottovalitata; di seguito un esempio tra le più banali ed utili:
- Conversione di formati con controllo valorizzazione
- Parsing di date se valide e non null (da a diversi formati)
- Parsing di flag (ad esempio Y/N) in booleani o null
- Conversione tra enumeratori
- Lettura e scrittura dati volatili comuni
- cache
- sessione
Wrapper di servizi
Una comodità, e spesso una necessità, è rappresentata dai wrapper di servizi, o il wrapper, a seconda del linguaggio può essere un metodo, una classe da estendere, una funzione o un servizio; sostanzialmente si tratta di un algoritmo, o una serie di algoritmi che vengono utilizzati prima e/o dopo ogni chiamata ai servizi http in modo da gestire opportunamente la predisposizione dati delle request, le casistiche di successo e di errore agendo sulle stesse per “reinterpretarle” dove necessario (sollevando eccezioni, reject o errore in caso di problematiche logiche come ad esempio i servizi soap). Di seguito alcuni vantaggi o logiche che è possibile integrare in funzionalità di questo tipo:
- Animazioni di caricamento (loader / spinner)
- Cache
- Gestione promise concorrenti (per lo stesso servizio con il medesimo input)
- Eventuali Header o input di configurazione
- Chiavi per i servizi di terze parti
- Header di identificazione
- Header o parametri per il tipo dati accettato
- Gestione degli errori centralizzata
- Mapping di codici di errore logici
- Mapping di codici HTTP
- Output automatico errori
- Modali / popup / snackbar / redirect
- Codici HTTP / messaggi logici di risposta
Suggerisco sempre di combinare il wrapper di servizi con dei file di costanti/configurazione, in modo da rendere ancora più utile e pratico lo strumento stesso.
Questo post è disponibile anche in: Inglese