Scegliere dove convalidare i dati non è soltanto una decisione tecnica: influisce sull’esperienza d’uso, sull’integrità aziendale e sui costi di gestione dell’applicazione. Mostrare un errore il prima possibile aiuta a compilare un modulo, ma non garantisce che un’operazione sia valida. D’altra parte, demandare tutti i controlli al server può proteggere i dati senza evitare attese e frustrazioni inutili.
La scelta più solida consiste nell’assegnare ogni regola al livello che può applicarla con le informazioni e l’autorità adeguate. L’interfaccia guida l’utente; il server protegge le regole di business; i processi asincroni gestiscono i controlli lenti o dipendenti da servizi esterni. In molti flussi, i tre livelli collaborano.
Perché un solo livello di convalida spesso non basta

Una convalida eseguita esclusivamente nell’interfaccia può essere rapida e chiara, ma è possibile aggirarla chiamando direttamente un’API, manipolando la richiesta o utilizzando un client diverso. Perciò non deve mai essere l’unica protezione di una regola che tutela dati o decisioni di business.
All’estremo opposto, convalidare tutto dopo l’invio costringe le persone ad aspettare per scoprire errori semplici, come aver lasciato vuoto un campo obbligatorio o aver scritto un indirizzo e-mail con un formato errato. Inoltre, alcuni controlli richiedono più tempo di una normale richiesta o dipendono da sistemi che potrebbero non essere disponibili.
La domanda utile non è «quale livello convalida i dati?», ma «quale livello offre la combinazione migliore di rapidità, autorità e contesto per ogni regola?». Per esempio, è possibile segnalare un limite di lunghezza nel browser e verificarlo di nuovo sul server. L’interfaccia migliora l’interazione; il server resta responsabile di accettare o rifiutare il dato.
Interfaccia: feedback immediato, non autorità definitiva
La convalida nell’interfaccia serve a individuare subito i problemi che si possono spiegare senza consultare fonti esterne: campi vuoti, limiti di caratteri, formati di base o combinazioni semplici. Riduce i tentativi non riusciti e aiuta a capire che cosa manca prima di inviare il modulo.
Per essere utile, il messaggio dovrebbe comparire accanto al campo o in un riepilogo accessibile, spiegare il problema e suggerire come risolverlo. È meglio evitare errori prematuri che interrompono l’utente mentre sta ancora scrivendo. Una pratica ragionevole consiste nel controllare il campo quando l’utente lo lascia o invia il modulo, aggiornando il messaggio quando il valore cambia.
L’interfaccia può anche anticipare limiti noti, come il formato atteso per una data. Tuttavia, non deve considerare valida un’azione solo perché il modulo la accetta. Il browser potrebbe non essere aggiornato, il client potrebbe essere modificato e la richiesta potrebbe arrivare da un altro canale.
- Usala per fornire feedback rapido e applicare regole semplici che facilitano l’inserimento dei dati.
- Non farci affidamento per autorizzazioni, permessi, prezzi definitivi o integrità dei record.
- Indica chiaramente i limiti ed evita messaggi che rivelano informazioni sensibili.
Server: autorità sulle regole di business
Il server deve verificare nuovamente ogni condizione la cui violazione possa alterare dati, concedere accessi non autorizzati o portare a una decisione errata. Questo include controllare che l’utente possa eseguire l’operazione, che i valori rientrino nel contesto autorizzato e che le transizioni di stato siano consentite.
Il controllo deve avvenire nel punto in cui il dato viene accettato o modificato, non soltanto in una schermata specifica. Se più applicazioni utilizzano la stessa API, il server garantisce una politica comune. Deve inoltre gestire le condizioni di concorrenza: due richieste possono contendersi una risorsa o tentare di modificare lo stesso record.
La convalida sul server non elimina la necessità di fornire messaggi comprensibili. Quando è sicuro farlo, la risposta dovrebbe distinguere tra un dato malformato, una regola di business non rispettata e una mancanza di autorizzazione. È meglio non restituire dettagli interni, query, tracce o informazioni che possano aiutare a sfruttare il sistema. Le raccomandazioni OWASP sulla convalida degli input sono un riferimento utile per trattare come non attendibili i dati ricevuti.
Regola pratica: se il risultato protegge una decisione o l’integrità del sistema, l’ultima parola spetta al server, anche quando l’interfaccia applica un controllo equivalente per rendere l’esperienza più fluida.
Processi asincroni: dipendenze esterne e risultati tardivi
Alcune regole non si possono verificare con un controllo locale o con una singola richiesta rapida. Controllare un indirizzo tramite un servizio esterno, analizzare un file o completare una revisione che richiede tempo può lasciare l’invio iniziale in stato di attesa.
In questi casi, separa la ricezione della richiesta dal risultato definitivo. Il sistema può confermare di aver ricevuto l’operazione e indicare che è in corso, senza affermare che sia già valida. Una volta terminato il controllo, deve aggiornare lo stato e comunicare il risultato tramite un meccanismo adeguato al prodotto, come una schermata di monitoraggio o una notifica.
Progetta anche la gestione degli errori: che cosa succede se il servizio esterno non risponde, restituisce un risultato inconcludente o torna disponibile dopo un’interruzione? Definisci limiti di attesa, tentativi successivi ragionevoli e una modalità di revisione o recupero. Un timeout non dimostra che il dato sia invalido: può significare che non è stato possibile completare il controllo.
Se il risultato può arrivare dopo che l’utente ha lasciato la schermata, lo stato deve restare consultabile. Evita che una risposta tardiva sovrascriva una modifica più recente: associa il risultato all’operazione o alla versione sottoposta a controllo.
Decidere dove collocare ogni regola
Valuta ogni controllo ponendoti quattro domande: quanto costa un errore? Quali informazioni servono? Quanto tempo occorre per ottenerle? Chi ha l’autorità per decidere? Queste domande aiutano a distinguere regole che spesso vengono mescolate in un unico modulo.
- Esperienza: se il controllo è semplice e l’errore si può correggere subito, mostrane l’esito nell’interfaccia.
- Sicurezza e integrità: se riguarda permessi, dati persistenti o una decisione economica, applicalo sul server.
- Dipendenze e latenza: se richiede servizi remoti o un’analisi prolungata, mostra uno stato di attesa e gestisci il risultato in seguito.
- Costo dell’errore: quanto maggiore è l’impatto dell’accettazione di un valore errato, tanto più servono controlli e tracciabilità.
Una regola può richiedere più livelli, ma non è necessario che tutti la verifichino con lo stesso grado di dettaglio. L’interfaccia può controllare che un campo non sia vuoto; il server può applicare anche vincoli di contesto e permessi. La ridondanza è utile quando ogni controllo ha uno scopo preciso.
Coerenza senza duplicare le regole in modo divergente
Il rischio di ripetere una regola è che cambi in un livello e non negli altri. L’interfaccia potrebbe accettare un valore che il server rifiuta, oppure bloccarne uno valido. Per ridurre queste divergenze, definisci le regole di business usando un’unica fonte di verità identificabile e mantieni contratti chiari tra client e API.
Quando l’architettura lo consente, si possono condividere schemi o componenti di convalida tra client e server. Questo non rende il client un’autorità: il server deve eseguire il controllo anche al proprio confine di fiducia. Se non è possibile condividere l’implementazione, documenta i criteri, i casi limite e le risposte attese, quindi aggiungi test per entrambi i livelli.
Presta particolare attenzione alle regole che cambiano nel tempo o dipendono dall’utente, dalla regione, dallo stato di un account o dalla disponibilità di una risorsa. Non codificare nell’interfaccia, come costanti, decisioni che il server può aggiornare. Se invii al client vincoli a scopo informativo, trattali come indicazioni che potrebbero essere obsolete.
Errori che indicano che cosa fare dopo
Un errore utile identifica il dato interessato, spiega il motivo senza gergo tecnico e propone il passo successivo. Se è possibile correggerlo prima dell’invio, associane il messaggio al campo. Se l’operazione è già in corso, spiegane lo stato generale e indica come verificarla o ripeterla. Per evitare duplicati in caso di nuovo tentativo, il progetto deve prevedere che cosa succede se la prima richiesta è stata completata ma la risposta non è arrivata al client.
Non usare un messaggio relativo a un campo per una condizione che dipende dallo stato complessivo del processo. Per esempio, se una risorsa non è più disponibile, occorre spiegare il cambiamento e offrire alternative, non limitarsi a segnalare come errato il formato del campo. Se non è sicuro rivelare la causa esatta, fornisci una spiegazione neutra e un canale per proseguire.
Lista di controllo prima del lancio

- Elenca le regole e indica quali riguardano il formato, il business, l’autorizzazione o le dipendenze esterne.
- Verifica che ogni regola critica venga controllata sul server prima di accettare la modifica.
- Controlla che i messaggi dell’interfaccia siano tempestivi, accessibili e utili per correggere l’errore.
- Definisci gli stati di attesa, gli errori temporanei, i nuovi tentativi e la gestione delle risposte tardive.
- Prova le richieste dirette all’API, i valori limite, i permessi e le modifiche concorrenti.
- Assicurati che gli errori non espongano dati interni e indichino il passo successivo.
- Assegna i responsabili dell’aggiornamento delle regole condivise quando cambia il prodotto.
Il progetto migliore non convalida tutto ovunque e non aspetta sempre il server. Combina feedback tempestivo, un’autorità ben definita e una gestione esplicita dei controlli tardivi. In questo modo l’applicazione è più comprensibile per chi la usa e più resistente a dati non validi, cambiamenti di contesto e problemi delle dipendenze.
