Wo und was sind die Ressourcen?
Bei REST geht es darum, Ressourcen auf zustandslose, erkennbare Weise anzusprechen. Es muss weder über HTTP implementiert werden, noch muss es sich auf JSON oder XML stützen. Es wird jedoch dringend empfohlen, ein Hypermedia-Datenformat zu verwenden (siehe das HATEOAS- Prinzip), da Links und IDs wünschenswert sind.
Die Frage lautet also: Wie denkt man über Synchronisation in Bezug auf Ressourcen?
Was ist bidirektionale Synchronisierung? **
Bei der bidirektionalen Synchronisierung werden die in einem Knotendiagramm vorhandenen Ressourcen aktualisiert, sodass am Ende des Prozesses alle Knoten ihre Ressourcen gemäß den Regeln für diese Ressourcen aktualisiert haben. In der Regel bedeutet dies, dass auf allen Knoten die aktuellste Version der Ressourcen im Diagramm vorhanden ist. Im einfachsten Fall besteht der Graph aus zwei Knoten: lokal und entfernt. Lokal initiiert die Synchronisierung.
Die Schlüsselressource, die angesprochen werden muss, ist also ein Transaktionsprotokoll. Daher könnte ein Synchronisierungsprozess für die Auflistung "items" unter HTTP folgendermaßen aussehen:
Schritt 1 - Lokal ruft das Transaktionsprotokoll ab
Lokal: GET /remotehost/items/transactions?earliest=2000-01-01T12:34:56.789Z
Remote: 200 OK, wobei der Body ein Transaktionsprotokoll enthält, das ähnliche Felder enthält.
itemId
- eine UUID zur Bereitstellung eines gemeinsam genutzten Primärschlüssels
updatedAt
- Zeitstempel, um einen koordinierten Zeitpunkt für die letzte Aktualisierung der Daten anzugeben (vorausgesetzt, ein Änderungsverlauf ist nicht erforderlich)
fingerprint
- Ein SHA1-Hash des Dateninhalts zum schnellen Vergleich, wenn updateAt
einige Sekunden vergangen sind
itemURI
- eine vollständige URI für den Artikel, um ihn später abrufen zu können
Schritt 2 - Local vergleicht das Remote-Transaktionsprotokoll mit seinem eigenen
Dies ist die Anwendung der Geschäftsregeln für die Synchronisierung. In der Regel itemId
wird die lokale Ressource identifiziert und anschließend der Fingerabdruck verglichen. Wenn es einen Unterschied gibt, wird ein Vergleich von durchgeführt updatedAt
. Wenn diese zu nah am Anruf sind, muss eine Entscheidung getroffen werden, basierend auf dem anderen Knoten zu ziehen (vielleicht ist es wichtiger) oder auf den anderen Knoten zu pushen (dieser Knoten ist wichtiger). Wenn die Remote-Ressource nicht lokal vorhanden ist, wird ein Push-Eintrag vorgenommen (dieser enthält die tatsächlichen Daten zum Einfügen / Aktualisieren). Alle lokalen Ressourcen, die nicht im Remote-Transaktionsprotokoll vorhanden sind, werden als unverändert angenommen.
Die Pull-Anforderungen werden an den Remote-Knoten gesendet, sodass die Daten lokal über den vorhanden sind itemURI
. Sie werden erst später lokal angewendet.
Schritt 3 - Lokales Synchronisationstransaktionsprotokoll an Remote senden
Lokal: PUT /remotehost/items/transactions
mit Hauptteil, der das lokale Synchronisierungstransaktionsprotokoll enthält.
Der entfernte Knoten kann diese synchron verarbeiten (wenn es klein und schnell) oder asynchron (man denke an 202 AKZEPTIERT ) , wenn es wahrscheinlich ist , eine Menge Aufwand entstehen. Unter der Annahme einer synchronen Operation lautet das Ergebnis je nach Erfolg oder Misserfolg entweder 200 OK oder 409 CONFLICT . Bei einem 409 CONFLICT muss der Prozess erneut gestartet werden, da auf dem Remote-Knoten ein optimistischer Sperrfehler aufgetreten ist (jemand hat die Daten während der Synchronisierung geändert). Die Fernaktualisierungen werden unter ihrer eigenen Anwendungstransaktion verarbeitet.
Schritt 4 - Lokal aktualisieren
Die in Schritt 2 abgerufenen Daten werden lokal im Rahmen einer Anwendungstransaktion angewendet.
Das oben Genannte ist zwar nicht perfekt (es gibt mehrere Situationen, in denen lokale und entfernte Geräte Probleme verursachen können und das Abrufen von Daten von lokalen Geräten wahrscheinlich effizienter ist als das Einfügen in einen großen PUT), es zeigt jedoch, wie REST während eines Bi- Richtungssynchronisationsprozess.