Wie kann die Wiederholung der Geschäftslogik zwischen Client und Server vermieden werden?

Lesezeit: 11 Minuten

Benutzer-Avatar
Röland

Da die Anforderungen an Webanwendungen gewachsen sind, habe ich festgestellt, dass ich immer mehr API-gesteuerte Webanwendungen schreibe. Ich verwende Frameworks wie AngularJS, um Rich-Web-Clients zu erstellen, die mit diesen APIs kommunizieren. Derzeit verwende ich PHP (Lumen oder Laravel) für die Serverseite / API.

Das Problem ist, dass ich häufig die Geschäftslogik zwischen der Client- und der Serverseite wiederhole.

Wenn ich Geschäftslogik sage, meine ich Regeln wie die folgenden für ein Bestellformular:

  • Du kannst X kaufen, wenn du Y kaufst.
  • Du kannst Y nicht kaufen, wenn du Z hast.
  • Wenn Sie 10 davon kaufen, erhalten Sie 10 % Rabatt.
  • Höhe x Breite x Tiefe x Kosten = Endkosten.
  • Die Höhe muss zwischen 10 und 20 liegen, wenn Ihre Breite größer als 5 ist.
  • usw. usw.

Um diese App sowohl reaktionsschnell als auch schnell zu machen, wird die Logik für Berechnungen (zusammen mit anderer Geschäftslogik) auf der Clientseite ausgeführt. Da wir dem Client nicht vertrauen sollten, verifiziere ich diese Nummern dann erneut auf der Serverseite. Diese Logik kann ziemlich komplex werden und das Schreiben dieser komplexen Logik an beiden Stellen fühlt sich gefährlich an.

Mir fallen drei Lösungen ein:

  1. Machen Sie alles, was Geschäftslogik erfordert, einen Ajax-Aufruf an die API. Die gesamte Geschäftslogik befindet sich an einem Ort und kann einmal getestet werden. Dies könnte langsam sein, da der Kunde auf jede einzelne Änderung warten müsste, die er am Bestellformular vornimmt, um aktualisierte Werte und Ergebnisse zu erhalten. Eine sehr schnelle API würde dabei helfen. Der Hauptnachteil ist, dass dies möglicherweise nicht gut funktioniert, wenn Benutzer schlechte Verbindungen haben (mobile Geräte).

  2. Schreiben Sie die Geschäftslogik auf der Clientseite UND auf der Serverseite. Der Kunde erhält sofortiges Feedback, wenn er Änderungen am Formular vornimmt, und wir validieren alle Daten, sobald sie auf dem Server übermittelt werden. Der Nachteil hierbei ist, dass wir die gesamte Geschäftslogik duplizieren und beide Seiten testen müssen. Dies ist sicherlich mehr Arbeit und würde die zukünftige Arbeit fragil machen.

  3. Vertrauen Sie dem Kunden!?! Schreiben Sie die gesamte Geschäftslogik auf der Clientseite und gehen Sie davon aus, dass die Daten nicht manipuliert wurden. In meinem aktuellen Szenario arbeite ich an einem Angebotsersteller, der immer von einem Menschen überprüft wird, also ist das vielleicht in Ordnung.

Ehrlich gesagt bin ich über keine der Lösungen glücklich, weshalb ich mich an die Community wende, um Rat zu erhalten. Ich würde gerne Ihre Meinungen oder Ansätze zu diesem Problem hören!

  • Hat Ihr Problem nicht einfach das MVC-Entwurfsmuster als Lösung?

    – Abhishek

    29. Mai 2016 um 6:32 Uhr

  • Die Verwendung von PHP auf Server-Ajax ist der coolste Ansatz und sollte nicht länger als ein paar ms dauern. Außerdem können Sie Ladebildschirme oder Warnungen festlegen, wenn dies länger dauert. Sie können zu einem Framework wie Meteor/Knoten wechseln, wo Sie das Ganze einmal codieren, und einige Details nur für Server oder Client explizit machen. Sie können grundlegende Validierungen in HTML-Formularen und dann die großen auf dem Server durchführen. Sie können Bibliotheken in js erstellen, auf die der Client und der Server zugreifen können. Schau dir das an php.net/manual/en/v8js.executestring.php

    – Christo

    31. Mai 2016 um 21:09 Uhr


  • Möge dieses andere Tuto, das ich gefunden habe, Sie interessieren: phpied.com/server-side-react-with-php

    – Christo

    31. Mai 2016 um 21:27 Uhr

  • Vielleicht könnten Sie mit einem Websocket arbeiten? Es ist sehr schnell und Sie können Javascript verwenden. Ich weiß ehrlich gesagt nicht, ob es viel Bandbreite verbraucht. Sie können bei Bedarf eine Verbindung zu diesem Websocket herstellen und die Verbindung trennen, wenn die Transaktion abgeschlossen ist. Websockets machen Spaß und sind sehr einfach zu implementieren. Ansehen Dies .

    – Thomas van der Veen

    2. Juni 2016 um 14:21 Uhr

  • Ich würde sowohl serverseitige als auch clientseitige Validierung verwenden; aber ich mag die Idee nicht, Code zu wiederholen, also würde ich höchstwahrscheinlich den Server die Validierungsregeln an den Client übergeben lassen und den Client diese Regeln konsumieren lassen, damit es eine Funktion ist, die alle Fälle validiert (alle Änderungen würden von der Serverseite vorgenommen daher würde der Client alle Änderungen immer noch korrekt validieren können), dann würde ich validieren, bevor ich auf der Serverseite speichere (endgültige Übermittlung).

    – Ahmed

    4. Juni 2016 um 14:10 Uhr

Benutzer-Avatar
Partha Sarathi Ghosh

Sie können noch etwas tun.

Erstellen Sie Ihren Validierungs- und Geschäftslogikcode nur mit JavaScript. Aber machen Sie es so weit wie möglich sehr locker gekoppelt. Wenn möglich, nehmen Sie nur JSON als Eingabe und geben Sie JSON als Ausgabe an.

Richten Sie dann neben dem vorhandenen PHP-Server einen separaten NodeJS-Server ein, um diese Logik für den Client bereitzustellen, sodass sie auf der Clientseite ohne AJAX-Aufruf verwendet werden kann.

Wenn Sie dann alle diese Geschäftslogikregeln validieren und ausführen müssen, verwenden Sie vom PHP-Server aus cURL, um die NodeJS-Geschäftslogik aufzurufen und die Daten zu validieren. Das bedeutet einen HTTP-Aufruf vom PHP-Server zum NodeJS-Server. Der NodeJS-Server verfügt über zusätzlichen Code, der die Daten übernimmt, mit demselben Code validiert und das Ergebnis zurückgibt.

Auf diese Weise können Sie machen

  1. Schnellere Entwicklung – Ein Ort, um Ihre Logik zu testen.
  2. Schnellere Client-Code-Ausführung – keine Notwendigkeit für AJAX, da derselbe Validierungs-JavaScript-Code von NodeJS an Ihren Client geliefert wird.
  3. Die gesamte Geschäftslogik befindet sich auf dem NodeJS-Server – Wenn sich die Geschäftslogik ändert, müssen Sie nur diesen Teil berühren; Wenn Sie also in naher Zukunft andere zusätzliche Schnittstellen erstellen müssen, können Sie diesen Server verwenden, um Ihre Daten zu validieren. Es funktioniert genauso wie Ihr Business Rule Server.

Das Einzige, was Sie tun müssen, ist Richten Sie neben Ihrem PHP-Server einen NodeJS-Server ein. Sie müssen jedoch nicht Ihren gesamten Code ändern, um auf dem NodeJS-Server ausgeführt zu werden.

  • Oder führen Sie zunächst die gesamte serverseitige Entwicklung im Knoten durch.

    – Mike Feltmann

    6. Juni 2016 um 17:38 Uhr

Ich hatte das gleiche Problem, als ich mich entschied, eine Anwendung mit Laravel für das Backend und Angular 2 für das Frontend zu erstellen. Und es scheint mir, dass es bisher keine Lösung gibt, um die Duplizierung der Geschäftslogik zu vermeiden, denn:

Derzeit können PHP und JavaScript nicht ineinander konvertiert werden. Wäre es schön, wenn wir dieselbe Sprache zum Schreiben der Geschäftslogik verwenden und sie dann sowohl in das Back-End als auch in das Front-End einbetten könnten. Von diesem Punkt führt es mich zu einem anderen Punkt:

Um das Ziel zu erreichen, sollten wir die Geschäftslogik in nur einer Sprache schreiben, und bisher ist JavaScript die beste Lösung. Wie Sie wissen, hilft uns TypeScript/EMCA Script, den Code auf OOP-Weise zu schreiben. Meteor Framework Die NodeJS-Infrastruktur hilft uns, Code in JavaScript zu schreiben, der sowohl im Back-End als auch im Front-End ausgeführt werden kann.

Aus meiner Sicht können wir also TypeScript/EMCA verwenden, um Pakete für Geschäftslogik zu schreiben, zum Beispiel kann eine in JavaScript geschriebene Klasse zur Validierung auf beiden Seiten implementiert werden, sodass Sie nur einmal schreiben, aber sie wird zweimal aufgerufen Frontend und Backend auch.

Das ist mein Punkt. Ich hoffe auf weitere Lösungen für dieses sehr interessante Thema.

  • Der Vorbehalt dabei ist, dass es eine Sprachänderung erfordert (zu nodejs von PHP). Es scheint, als wäre dies der einzige Weg, dies ohne Duplizierung zu tun 🙁

    – Röland

    1. Juni 2016 um 18:14 Uhr

  • Sie können Geschäftslogik in reinem Javascript verwenden und auf nodejs bereitstellen. Den Rest des Codes können Sie auf dem PHP-Server platzieren. Auf diese Weise müssen Sie nicht Ihren gesamten Code auf nodejs umstellen und können sich Ihre Doppelarbeit sparen. Schau dir meine Antwort an.

    – Partha Sarathi Ghosh

    7. Juni 2016 um 10:22 Uhr

Eine mögliche Lösung besteht darin, Ihre Validierungsregeln in einer deklarativen abstrakten Sprache wie XML oder JSON Schema zu deklarieren.

Dann auf der Client-Seite, sagen wir AngularJS – Sie können diese Regeln in einen Standard-Formular-Renderer umwandeln. Auf der Clientseite erhalten Sie nun also Formulare, die die deklarierten Regeln validieren.

Dann müssen Sie auf Ihrer serverseitigen API eine wiederverwendbare Validierungs-Engine erstellen, die basierend auf den definierten Regeln validiert.

Was Sie am Ende haben, ist ein einziger Ort, Ihr JSON-Schema oder wo immer Sie Ihre Regeln deklarativ definieren, an dem Ihre Formular- und Validierungsregeln definiert sind.

Ich war auch in dieser Position, als ich an einigen meiner eigenen Projekte gearbeitet habe. Es ist immer verlockend, die Leistung des Client-Geräts zu nutzen, um die schwere Arbeit zu erledigen, und die Ergebnisse dann einfach auf der Serverseite zu validieren. Dies führt dazu, dass die Geschäftslogik zweimal erscheint, sowohl im Front-End als auch im Back-End.

Ich denke, Option 1 ist die beste Option, sie macht am meisten Sinn und erscheint auch am logischsten. Wenn Sie Ihre Web-App in Zukunft auf native mobile Apps erweitern möchten, können Sie die gesamte Geschäftslogik durch Aufrufen dieser APIs wiederverwenden. Für mich ist das ein riesiger Gewinn.

Wenn Sie sich Sorgen machen, dass zu viele API-Anforderungen gestellt werden und dies die mobile Leistung beeinträchtigen könnte, versuchen Sie dann vielleicht, einige der Anforderungen zu gruppieren und am Ende eine einzelne Prüfung durchzuführen. Anstatt also jedes Feld in einem Formular zu überprüfen, führen Sie eine Überprüfung durch, wenn der Benutzer das gesamte Formular absendet. Auch die meisten Internetverbindungen werden ausreichen, wenn Sie die Anfrage- und Antwortdaten auf ein Minimum beschränken, also mache ich mir darüber keine Sorgen.

Ein größeres Problem, auf das ich normalerweise stoße, ist, dass Ihre Webanwendung in Abschnitte unterteilt wird, wobei jeder Abschnitt die relevanten APIs aufruft. Der Zustand der App ist viel komplexer zu verstehen, da der Benutzer zwischen diesen Zuständen springen könnte. Sie müssen sehr sorgfältig über die Benutzerreise nachdenken und sicherstellen, dass der Prozess nicht fehlerhaft ist.

Hier sind einige der häufigsten Probleme, mit denen ich mich befassen musste:

  • Zeigt das Front-End einen Fehler an, wenn die API einen zurückgibt?
  • Wenn der Benutzer einen Fehler gemacht und das Formular gesendet hat, sollte er/sie einen Fehler sehen. Aber sobald der Benutzer den Fehler behoben und erneut übermittelt hat, sollte der Fehler ausgeblendet und die Erfolgsmeldung angezeigt werden.
  • Was ist, wenn die API fehlerhaft oder die Internetverbindung instabil ist, sodass nichts zurückgegeben wird? Wird das Frontend hängen bleiben?
  • Was ist, wenn es mehrere Fehlermeldungen gibt, kann/zeigt das Front-End sie alle an?

Ich würde empfehlen, viele Einheitentests am Frontend durchzuführen, um sicherzustellen, dass es stabil ist, auch wenn sich die Geschäftslogik nur im Backend befindet.

Zunächst einmal: Traue niemals dem Kunden.

Davon abgesehen beschäftige ich mich die ganze Zeit damit, und leider habe ich keine einfache Lösung gefunden. Sie müssen die Validierung auf beiden Seiten durchführen, ABER Sie müssen nicht die gesamte Validierung auf beiden durchführen.

Was ich tue, ist, es auszugleichen. Auf der Client-Seite führen Sie die meisten einfachen (aber wertvollen) Validierungen durch, normale Dinge, Zahlen müssen Zahlen sein, Daten müssen Daten sein, Daten innerhalb des Bereichs usw. Wenn Sie sie also senden, geht sie an den Server, um sie vollständig zu erhalten validiert, aber Sie stellen auf der Clientseite sicher, dass die meisten Informationen zumindest im richtigen Format vorliegen und einige (oder die meisten) davon bereits validiert sind. Die eigentliche Geschäftslogik wird jedoch serverseitig ausgeführt , aber da die meisten Daten bereits korrekt sind, wird die serverseitige Validierung die Anfrage höchstwahrscheinlich genehmigen, sodass Sie viele erneute Übermittlungen vermeiden.

Nun, wie macht man es so, dass man, wenn man etwas ändern muss, es nicht auf beiden Seiten ändern muss? Nun, manchmal werden Sie dies nicht vermeiden können, wenn größere Änderungen erforderlich sind, ABER Geschäftslogikparameter können gemeinsam genutzt werden, und wie Sie vorgeschlagen haben, kann dies über Ajax erfolgen. Sie erstellen eine PHP-Datei, in der Sie alle Ihre Geschäftslogikparameter haben, und mit einer Ajax-Anfrage laden Sie diese auf der Clientseite, nur einmal (wenn das Skript geladen ist), müssen Sie diese optimieren, sodass Sie nur die Parameter erhalten Werte, alles andere sollte bereits auf der Client-Seite vorhanden sein, wenn sich also ein Parameterwert in der Geschäftslogik ändert, ändern Sie ihn nur in Ihrer Parameterdatei. (Wenn ein Parameter geändert wird, nachdem das Skript geladen wurde, schlägt die Validierung auf der Serverseite fehl. Jetzt müssen Sie entscheiden, ob Sie sie zum erneuten Laden des Skripts zwingen, damit die Parameter neu geladen werden, oder nicht, ich lasse sie neu laden.)

Ich denke, du verstehst es. Das ist, was ich tue, und es funktioniert ziemlich gut für mich, erspart mir eine Menge Neucodierung.

Ich hoffe, Sie finden das hilfreich.

Benutzer-Avatar
Gco-Software

Option 1 ist meines Erachtens die beste Lösung für die Zukunft. Die API-Erstentwicklung ermöglicht es, die gesamte Geschäftslogik zu testen und ordnungsgemäß zu funktionieren und den Zugriff auf Schnittstellen zu ermöglichen. Sie sollten dem Benutzer NIEMALS vertrauen!

Die Leistung der API-Erstentwicklung ist unbegrenzt im Vergleich dazu, dieselbe Logik immer wieder für jede benötigte Schnittstelle zu codieren.

Benutzer-Avatar
Gemeinschaft

Hier ist ein ähnlicher Thread darüber, ob Logik clientseitig oder serverseitig platziert werden soll. Letztendlich ist jede Situation einzigartig und rechtfertigt einen anderen Plan, aber es gibt einige gute, richtungsweisende Tipps in diesem Thread.

Clientseitig vs. Serverseitig

1158340cookie-checkWie kann die Wiederholung der Geschäftslogik zwischen Client und Server vermieden werden?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy