Kontext
Aufgrund der Staatenlosigkeit des REST-Architekturstils, bei der jede Anforderung vollständig für sich steht, speichert der Server niemals Informationen über den Client.
Daher ist eine pessimistische Parallelitätskontrolle nicht geeignet, da der Server speichern müsste, welcher Client die Sperre für eine Ressource erhält. Anschließend wird mithilfe des Etag
Headers eine optimistische Parallelitätssteuerung verwendet . (Übrigens, wie ich dort gefragt habe /programming/30080634/concurrency-in-a-rest-api )
Problem
Das Hauptproblem bei einem optimistischen Mechanismus zur Kontrolle der Parallelität besteht darin, dass Sie jederzeit allen Clients erlauben, alle Vorgänge auszuführen.
Und das möchte ich vermeiden, ohne das Prinzip der Staatenlosigkeit von REST zu brechen. Ich meine, dass nicht alle Clients zu irgendeinem Zeitpunkt eine Operation ausführen können.
Frage
In meinem Kopf, wäre es möglich , mit einem halb optimistisch Nebenläufigkeitssteuermechanismus, wie folgt aus:
- Clients können ein Token anfordern
- Es kann nur ein Token generiert werden und hat eine begrenzte Gültigkeitsdauer
- Um Operationen an Ressourcen (wie POST oder PUT ) auszuführen , muss der Client dieses Token als Teil des Hauptteils (oder Headers?) Der Anforderung angeben. Clients, die nicht über das Token verfügen, können diese Vorgänge nicht ausführen.
Es ist der optimistischen Parallelitätskontrolle sehr ähnlich, außer dass nur ein Client einige Operationen ausführen kann (derjenige, der das Token erhalten hat) ... im Gegensatz zu "Alle Clients können alle Operationen ausführen".
Ist dieser Mechanismus mit einem REST-Architekturstil kompatibel? Bricht es eine seiner Einschränkungen? Ich habe überlegt, nach SO zu fragen, aber dies scheint eher eine allgemeine Frage zu sein, die sich auf das Software-Design bezieht.
quelle
Transaction
explizit als Ressource modellieren .Etag
? WennEtag
Sie nie sicher sind, ob Ihre Operationen abgeschlossen sind, können Sie eine Situation haben, in der Sie niemals irgendwelche Operationen ausführen werden. Mit einem Schloss können Sie sicher sein, dass Sie zumindest Ihre Operation ausführen. Eine einfache Sperre ist also nur eine Mitte zwischen einer Umgebung, in der "hohe Konflikte" und "seltene Konflikte" auftreten können.Antworten:
Sie sollten niemals (wie nie zuvor) eine Ressource sperren, während Sie auf eine Benutzerinteraktion warten.
Irgendwann werden einige Ihrer Benutzer für ein langes Wochenende abheben und einige wichtige Datensätze gesperrt lassen.
Ah, aber Sie werden das nicht zulassen, weil Sie ein cleveres Timeout / Deadlock-Auflösungsschema haben. Dann wird dies irgendwann schrecklich schief gehen und ein Benutzer, der eine nette Nachricht "Ihr Widget wurde bestellt" erhalten hat, wird am Helpdesk schreien und fragen, warum sein Widget nicht geliefert wurde.
Die meisten Leute können mit der Nachricht "Entschuldigung, ein anderer Benutzer hat gerade diesen Teil bestellt" umgehen.
quelle
Die Verwendung von Token ist in APIs sehr verbreitet. Diese Token werden normalerweise als Header gesendet und haben einen klaren Lebenszyklus. Denken Sie zum Beispiel an OAuth.
Unabhängig von Ihrer Programmiersprache oder Ihrem Framework sind die REST-APIs ähnlich.
Ich kann mir mehrere Szenarien vorstellen, in denen Sie die Parallelität begrenzen möchten. Zwei davon sind:
Mehrere Clients aktualisieren dieselben Ressourcen wie eine Datenbankzeile. Beispiel: Zwei gleichzeitige Anforderungen, eine löscht einen Datensatz und die andere versucht, denselben Datensatz zu aktualisieren. Abhängig von Ihrer Datenbank und wie Sie sie eingerichtet haben, erhalten Sie möglicherweise eine Sperre für die Datensätze oder einen ungültigen Vorgang, da die Daten unterschiedlich sind oder nicht vorhanden sind.
Ein Superuser oder Administrator, der spezielle Aktionen mit der API ausführt.
Was ist in diesen Fällen zu tun?
Verwenden Sie Transaktionen in der Datenbank, Singletons, Sperren und ähnliche Mechanismen, um den Zugriff auf die Ressourcen zu synchronisieren.
Das Token könnte funktionieren. Ich denke, es ist besser, wenn Sie keine Informationen über den Client speichern, sondern nur über das Token selbst. In einem Schritt können Sie den Benutzer validieren und das Token zuweisen. Überprüfen Sie dann einfach, ob das Token aktiv und gültig ist. Verwenden Sie ein Token, das entschlüsselt werden kann, um zusätzliche Informationen zu erhalten. Sie können speichern, ob dies ein spezielles Token ist, und es jeweils nur zulassen. Auf diese Weise validieren Sie das Token und nicht den Benutzer.
Ich hoffe das hilft.
quelle
REST alleine ist wirklich zu primitiv. Sie können mit REST beginnen, aber schließlich benötigt Ihre umfangreiche Anwendung Abfragen mit Verknüpfungen und Aktualisierungen mit Transaktionen. Jeder Entwickler, der versucht, diese Dinge selbst hinzuzufügen, wäre fehleranfällig und inkonsistent. Glücklicherweise gibt es einen neuen Standard namens OData, der genau das tut. Es wird über REST gelegt und bietet (1) eine Abfragesprache, die einfache Verknüpfungen mithilfe von Navigationseigenschaften ermöglicht (ohne dass Fremdschlüssel verfügbar gemacht werden müssen), und (2) eine Stapelverarbeitung, die atomare Änderungssätze enthält.
Siehe hier für (1) https://stackoverflow.com/a/3921423/471129 und,
Siehe hier und für (2) https://stackoverflow.com/a/21939972/471129
quelle