Verwalten von clientseitigen und serverseitigen Überprüfungen an einem Ort

17

Ich bin zu 100% mit dem Fall einverstanden, dass man auf jeden Fall sowohl clientseitige als auch serverseitige Datenvalidierungen verwenden sollte.

In den Frameworks und Umgebungen, in denen ich gearbeitet habe, waren die Ansätze, die ich gesehen habe, noch nie TROCKEN. Meistens gibt es keinen Plan oder kein Muster - Validierungen werden in die Modellspezifikation und Validierungen in das Formular in der Ansicht geschrieben. (Hinweis: Die meisten meiner Erfahrungen aus erster Hand liegen mit Rails, Sinatra und PHP mit jQuery vor.)

Wenn man darüber nachdenkt, scheint es nicht schwierig zu sein, einen Generator zu erstellen, der bei einer Reihe von Validierungen (z. B. Modellname, Feld (er), Bedingung) sowohl das erforderliche clientseitige als auch das serverseitige Material produzieren könnte. Alternativ könnte ein solches Tool die serverseitigen Überprüfungen (z. B. den validatesCode in einem ActiveRecord-Modell) verwenden und clientseitige Überprüfungen (z. B. jQuery-Plugins) generieren, die dann auf das Formular angewendet werden.

Offensichtlich ist das oben Gesagte nur ein "Hey, ich hatte diese Idee" und kein formeller Vorschlag. So etwas ist sicherlich schwieriger, als es schien, als die Idee mich traf.

Das bringt mich zu der Frage: Wie würden Sie vorgehen, um eine Technik zum einmaligen Schreiben, Ausführen auf Server und Client für die Datenüberprüfung zu entwerfen?

Verwandte Unterthemen: Gibt es solche Tools für bestimmte Frameworks oder Client-Server-Technologien? Was sind die Hauptprobleme oder Herausforderungen bei dem Versuch, nur einen Satz von Validierungen beizubehalten?

asfallows
quelle

Antworten:

6

Nach meiner begrenzten Erfahrung sind die Punkte zu überprüfen, an denen eine Validierung erforderlich ist

  1. Die Präsentationsebene mit HTML,
  2. auf der Postpräsentationsebene (dh Javascript-Validierung),
  3. auf der Kombinationsebene, auf der Interaktionen zwischen mehreren Feldern zusammen validiert werden müssen,
  4. auf der Ebene der Geschäftslogik und
  5. auf Datenbankebene.

Jeder von ihnen hat verschiedene Sprachen, Zeiten und Auslöser. Es ist beispielsweise wenig sinnvoll, ein Feld zu validieren, bevor sich der gesamte Datensatz in einem konsistenten Zustand befindet, es sei denn, Sie möchten nur ein Teil validieren. Einschränkungen auf Datenbankebene müssen erst am Ende vor einem Commit gelten und können nicht ohne Weiteres einzeln ausgeführt werden.

Ein verwandtes Konzept ist, dass die Darstellung von Daten zwischen den einzelnen Ebenen variiert. Ein einfaches Beispiel ist, dass ein Webbrowser einen Textabschnitt wie CP1290 darstellt, während die Datenbank ihn in UTF-8 darstellt. Die Längen der beiden Zeichenfolgen unterscheiden sich, sodass die Durchsetzung von Längenbeschränkungen umständlich wird.

BobDalgleish
quelle
Ja, verschiedene Sprachen und Rahmenbedingungen machen dies unpraktisch. Nicht "rückgängig" zu machen, da dies mit genügend Ressourcen möglich ist, aber das Schreiben von Autokonvertern in und zwischen Sprachen ist eine GROSSE Aufgabe. Es wäre eine Menge Arbeit, dies in einem angemessenen Zeitrahmen zu tun und es dann beizubehalten, wenn sich die relevanten Technologien ändern.
Michael Durrant
Es ist definitiv richtig, dass viele serverseitige Überprüfungen (z. B. Eindeutigkeit eines Feldes) nicht im Browser durchgeführt werden können. Es ist jedoch auch richtig, dass clientseitige Überprüfungen auf dem Server wiederholt werden müssen, da Sie dem Client nicht vertrauen können. Hier sehe ich DRYING Dinge als besonders nützlich. Zum Beispiel könnte ich sehen, dass ein Juwel, das Rails 'erweitert, form_forum automatisch clientseitigen Validierungscode bereitzustellen, sehr nützlich ist.
Dan
5

Eine Überlegung, die Lösungen häufig einschränkt, ist der Netzwerk-Roundtrip. Der Client soll die Benutzerdaten validieren, ohne eine Nachricht über das Netzwerk zu senden. Mit anderen Worten, wenn der Benutzer die Senden-Schaltfläche drückt, soll der Client die Daten lokal validieren.

Nehmen wir zunächst an, dass wir diese Einschränkung nicht haben. Wir könnten mit einem Netzwerkendpunkt kommunizieren, der Validierungsprobleme gut artikulieren kann. Wenn Sie beispielsweise Ihren neuen Benutzerdatensatz an diesen senden, anstatt mit einem Vanilla-HTTP-Fehlercode zu antworten, wird möglicherweise eine ausführliche JSON-Antwort zurückgegeben, in der die Probleme aufgeführt sind, und der Client aktualisiert die Anzeige intelligent, um die aufgetretenen Probleme widerzuspiegeln. Der Endpunkt spielt die Rolle eines Validierungsgateways.

Es ist trocken, aber nicht ohne Nachteile. Erstens hängt es von der Netzwerk-Roundtrip ab, die unseren Server mit Überprüfungen belastet, die clientseitig hätten durchgeführt werden können. Zweitens geht das Design davon aus, dass alle CRUD-Vorgänge über unsere Endpunkte erfolgen. Wie sieht es jedoch aus, wenn Entwickler und Prozesse unsere Datenzugriffsschicht umgehen, indem sie direkt auf die Datenbank zugreifen ?

Lassen Sie uns unsere Lösung überdenken, um diese Nachteile zu überwinden. Speichern und kommunizieren wir stattdessen unsere Validierungen als Metadaten:

{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']}

Sowohl der Client als auch der Server verfügen über einen Mechanismus (z. B. eine Engine) zum Interpretieren und Anwenden dieser Daten. (Einige nennen dies die freie Monade, da sie den deklarativen Teil von seinem Interpreter trennt.) In JavaScript konnten wir jede Information auf Arbeitsfunktionen abbilden. Um zu booten, können wir jede Ebene unserer Architektur, einschließlich unserer Datenbank, lehren, Validierungen konsistent durchzusetzen.

Mario T. Lanza
quelle
Wie beschreiben Sie ein Feld, wenn ein Feld in Webbrowser, Transport, Implementierungssprache und Datenbank unterschiedlich dargestellt wird? Die Anzahl der für die Darstellung eines Zeichenfolgenfelds erforderlichen Bytes variiert beispielsweise bei Verwendung von CP1290 (IE), UTF-8 (JSON), UTF-8 (C #) oder UCS-16 (Oracle). Was bedeutet eine Längenbeschränkung? Noch wichtiger für den Browser, wenn die Zeichendarstellung vom Browser und Betriebssystem abhängt?
BobDalgleish
Diese Einschränkungen sind als mentales Modell für den Menschen gedacht. Als Programmierer müssen Sie die Unterschiede zur Maschine abstrahieren, damit sich die Person nicht um technische Unterschiede kümmern muss.
Mario T. Lanza
Sie haben den Punkt völlig verpasst. Bisher hat niemand eine Abstraktion vorgestellt, die eine Validierung von Ende zu Ende mit einer Spezifikation ermöglicht. Vom OP aus bedeutet "einmal schreiben", dass unterschiedliche Klauseln, die unterschiedliche Stadien ansprechen, nicht qualifiziert sind. Ebenso sehe ich in Ihrer vorgeschlagenen Validierung nichts, was die Interfeld- oder Interobjektvalidierung betrifft.
BobDalgleish
Interfield- / Objektvalidierungen sind nicht sehr aufwändig. Die Metadaten stellen nur die Beziehung dar. Einmal schreiben bedeutet, dass ich eine einzelne Validierung einmal schreibe und sie an mehreren Standorten erzwingen lasse, was auch der Fall ist. Sie fügen einer Tabelle Metadaten hinzu. Diese Metadaten werden von jeder Site empfangen und eine einfache Klasse / Utility / Engine erzwingt die Einschränkung.
Mario T. Lanza
1
Eine solche Validierungssprache wäre äußerst nützlich. Es könnte möglicherweise ein Drittel des Codes für UI-intensive Webanwendungen ersetzen.
BobDalgleish
2

Eine Möglichkeit wäre, sowohl auf der Server- als auch auf der Clientseite dieselbe Sprache / dasselbe Framework zu verwenden.

Z.B

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

In diesem Fall ist der größte Teil des "Domain Object" -Codes gemeinsam, was eine Validierung einschließt. Framework ruft den Code nach Bedarf auf. ZB wird derselbe Code im Browser vor "Submit" und auf dem Server aufgerufen.

EDIT (Juni / 2014): Mit Java 8 ist es jetzt einfach, JS-Validierungscode auch in Java-Anwendungen zu integrieren. Java 8 verfügt über eine neue, dauerhaftere JS-Ausführungs-Engine (z. B. invokeDynamic).

Schamit Verma
quelle
Wenn es um die SQL-Datenbank geht, bin ich mir nicht sicher, wie das funktionieren würde.
Michael Durrant
Es löst auch nicht das Problem, dass der Browser und das Betriebssystem die Eingabedomäne beeinflussen.
BobDalgleish
@Micheal Durrant, Für die Datenbanküberprüfung werden DB-Einschränkungen (wie Fremdschlüssel, Eindeutigkeit usw.) implementiert. BobDalgleish, 1. Probleme mit der Browser- / Betriebssystemkompatibilität können durch die Verwendung einer Bibliothek verringert werden, die die Laufzeit je nach Browser optimiert (z. B. Sencha) rund um DOM / UI-Rendering.
Shamit Verma
0

Ich habe nur über das gleiche Problem nachgedacht. Ich wollte ANTLR verwenden, um einen abstrakten Syntaxbaum sowohl in C # als auch in Javascript zu erhalten. Von dort aus verwenden Sie Tree Walker, um die in der Sprache angegebenen Aktionen auf die zu validierenden Objekte anzuwenden.

So können Sie, wo immer Sie möchten, eine Beschreibung der erforderlichen Validierung in der Datenbank speichern.

So würde ich das Problem angehen.

Marcus
quelle