Gestione delle convalide lato client e lato server in un'unica posizione

14

Sono 100% a bordo con il caso che uno dovrebbe definitivamente utilizza sia la convalida dei dati lato client che lato server.

Tuttavia, nei framework e negli ambienti in cui ho lavorato, gli approcci che ho visto non sono mai stati ASCIUTTI. La maggior parte delle volte non c'è un piano o modello - le convalide sono scritte nella specifica del modello e le convalide sono scritte nel modulo sulla vista. (Nota: la maggior parte della mia esperienza di prima mano è con Rails, Sinatra e PHP con jQuery)

Rimuginando, sembra che non sarebbe difficile creare un generatore che, dato un insieme di convalide (ad esempio nome del modello, campo (i), condizione), possa produrre sia il lato client necessario che il server materiale laterale. In alternativa, un tale strumento potrebbe richiedere le convalide sul lato server (come il codice validates in un modello ActiveRecord) e generare convalide sul lato client (come i plugin jQuery, che verrebbero quindi applicati al modulo.

Ovviamente, quanto sopra è solo un "hey ho avuto questa idea" di riflessione, e non una proposta formale. Questo tipo di cose è sicuramente più difficile di quello che sembrava quando l'idea mi ha colpito.

Questo mi porta alla domanda: Come ti appresti a progettare una tecnica "scrivi una volta, esegui su server e client" per la convalida dei dati?

Argomenti correlati: strumenti come quelli esistenti per qualsiasi framework o tecnologia client-server? Quali sono i principali trucchi o sfide con il tentativo di mantenere solo un set di convalide?

    
posta asfallows 25.04.2014 - 22:46
fonte

4 risposte

6

Nella mia esperienza limitata, i punti in cui è richiesta la convalida sono

  1. Il livello di presentazione usando HTML,
  2. a livello di post-presentazione (cioè convalida Javascript),
  3. al livello di combinazione in cui devono essere convalidate le interazioni tra più campi     insieme,
  4. a livello di business logic e
  5. a livello di database.

Ognuno di loro ha lingue, tempi e trigger diversi. Ad esempio, ha poco senso convalidare un campo prima che l'intero record sia in uno stato coerente, a meno che tu voglia convalidare solo un pezzo. I vincoli a livello di database devono essere applicabili solo alla fine prima di un commit e non possono essere fatti facilmente a livello di pezzo.

Un concetto correlato è che la rappresentazione dei dati varia tra ciascuno dei livelli. Un semplice esempio è un browser Web che rappresenta un pezzo di testo come, forse, CP1290, mentre il database lo rappresenta in UTF-8; le lunghezze delle due stringhe differiscono in modo tale da far impallidire i vincoli di lunghezza.

    
risposta data 26.04.2014 - 00:06
fonte
3

Una considerazione che spesso limita le soluzioni è l'andata e il ritorno della rete. Il client dovrebbe convalidare i dati dell'utente senza inviare un messaggio attraverso la rete. In altre parole, quando l'utente preme il pulsante di invio, il client deve convalidare i dati localmente.

In primo luogo, supponiamo di non avere questa limitazione. Potremmo comunicare con un endpoint di rete che è in grado di articolare i problemi di convalida. Ad esempio, quando si invia il nuovo record utente ad esso, anziché rispondere con un codice di errore HTTP vaniglia, potrebbe restituire una risposta JSON dettagliata che dettaglia i problemi e il client aggiornerebbe in modo intelligente la visualizzazione per riflettere i problemi incontrati. L'endpoint svolge il ruolo di un gateway di convalida.

È ASCIUTTO ma non privo di inconvenienti. Innanzitutto, dipende dal roundtrip della rete che impone il nostro server con convalide che potrebbero essere state gestite dal lato client. In secondo luogo, il progetto prevede che tutte le operazioni CRUD avverranno tramite i nostri endpoint, ma che dire di quando sviluppatori e processi ignorano il nostro livello di accesso ai dati andando su direttamente contro il database ?

Rivisitiamo la nostra soluzione per superare questi inconvenienti. Invece, memorizziamo e comunichiamo le nostre convalide come metadati:

{field: 'username', type: 'required'}
{field: 'username', type: 'unique'} //requires a network roundtrip
{field: 'password', type: 'length', min: 10, max: 50}
{field: 'password', type: 'contains', characters: ['upper', 'special', 'letter', 'number']}

Sia il client che il server avrebbero un meccanismo (ad esempio un motore) per l'interpretazione e l'applicazione di questi dati. In Javascript potremmo mappare ogni informazione a funzioni di lavoro. Per avviare, possiamo insegnare qualsiasi livello della nostra architettura, incluso il nostro database, per applicare le convalide in modo coerente.

    
risposta data 19.06.2014 - 15:46
fonte
2

Un modo sarebbe utilizzare lo stesso linguaggio / framework sia lato server che lato client.

es.

Node.js :: Client / Server in JavaScript GET :: Client / Server in Java

In questo caso, la maggior parte del codice "Oggetto dominio" sarebbe comune, che includerebbe la convalida. Framework invocherà il codice come richiesto. Per esempio. Lo stesso codice verrebbe richiamato nel browser prima di "inviare" e sul servizio web sul lato server.

EDIT (giugno / 2014): con Java 8, è ora facile integrare il codice di convalida JS anche in applicazioni Java. Java 8 ha un nuovo motore di esecuzione JS che è più permanente (E.g: fa uso di invokeDynamic).

    
risposta data 23.05.2014 - 15:33
fonte
0

Stavo solo pensando allo stesso problema. Stavo pensando di usare ANTLR per ottenere un albero di sintassi astratto sia in C # che in javascript. Da lì puoi utilizzare i tree walker per applicare le azioni specificate nella lingua agli oggetti da convalidare.

Quindi è possibile memorizzare una descrizione della convalida richiesta dove preferisci, eventualmente nel database.

Ecco come vorrei affrontare il problema.

    
risposta data 23.05.2014 - 13:16
fonte

Leggi altre domande sui tag