Zakładając, że w systemie jest aplikacja sieci Web z zasobem i odniesienie do aplikacji zdalnej z innym podobnym zasobem, w jaki sposób reprezentujesz dwukierunkową akcję synchronizacji, która synchronizuje zasób „lokalny” z zasobem „zdalnym”?
Przykład:
Mam interfejs API reprezentujący listę czynności do wykonania.
GET / POST / PUT / DELETE / todos / itp.
Ten interfejs API może odwoływać się do zdalnych usług TODO.
GET / POST / PUT / DELETE / todo_services / itp.
Mogę manipulować todos ze zdalnej usługi za pośrednictwem mojego interfejsu API jako proxy za pośrednictwem
GET / POST / PUT / DELETE / todo_services / abc123 / itd.
Chcę mieć możliwość dwukierunkowej synchronizacji między lokalnym zestawem zadań do zrobienia a zdalnym zestawem TODOS.
W pewien sposób można to zrobić
POST / todo_services / abc123 / sync /
Ale czy w idei „czasowniki są złe” istnieje lepszy sposób na przedstawienie tego działania?
źródło
GET /todo/1/
iPOST
to do/todo_services/abc123/
Ale, dwukierunkowa - nie biorę zestawu danych i nie umieszczam go w zasobie, działanie, które podejmuję, powoduje potencjalną modyfikację dwóch zasobów. Wydaje mi się, że mógłbym polegać na tym, że same „todo syncronizations” są zasobamiPOST /todo_synchronizations/ {"todos":["/todo/1/","/todo_services/abc123/1"],"schedule":"now"}
GET /todo_synchronizations/1
=>{"todos":["/todo/1/","/todo_services/abc123/1"],"schedule":"now","ran_at":"datetime","result":"success"}
Odpowiedzi:
Gdzie i jakie są zasoby?
REST polega na adresowaniu zasobów w sposób bezstanowy i możliwy do wykrycia. Nie musi być implementowany przez HTTP, ani nie musi polegać na JSON ani XML, chociaż zdecydowanie zaleca się stosowanie formatu danych hipermedialnych (patrz zasada HATEOAS ), ponieważ pożądane są linki i identyfikatory.
Powstaje zatem pytanie: jak ocenia się synchronizację pod względem zasobów?
Co to jest synchronizacja dwukierunkowa? **
Dwukierunkowa synchronizacja to proces aktualizowania zasobów obecnych na wykresie węzłów, tak aby pod koniec procesu wszystkie węzły zaktualizowały swoje zasoby zgodnie z regułami rządzącymi tymi zasobami. Zazwyczaj należy rozumieć, że wszystkie węzły miałyby najnowszą wersję zasobów obecnych na wykresie. W najprostszym przypadku wykres składa się z dwóch węzłów: lokalnego i zdalnego. Lokalny inicjuje synchronizację.
Tak więc kluczowym zasobem, który należy rozwiązać, jest dziennik transakcji, a zatem proces synchronizacji może wyglądać tak dla kolekcji „pozycji” w HTTP:
Krok 1 - Lokalny pobiera dziennik transakcji
Lokalny:
GET /remotehost/items/transactions?earliest=2000-01-01T12:34:56.789Z
Zdalny: 200 OK z treścią zawierającą dziennik transakcji zawierający pola podobne do tego.
itemId
- UUID w celu udostępnienia wspólnego klucza podstawowegoupdatedAt
- znacznik czasu zapewniający skoordynowany punkt ostatniej aktualizacji danych (przy założeniu, że historia zmian nie jest wymagana)fingerprint
- skrót SHA1 zawartości danych do szybkiego porównania, jeśliupdateAt
upłynie kilka sekunditemURI
- pełny identyfikator URI elementu, aby umożliwić późniejsze pobranieKrok 2 - Lokalny porównuje zdalny dziennik transakcji z własnym
Jest to zastosowanie reguł biznesowych dotyczących synchronizacji. Zazwyczaj
itemId
identyfikuje zasób lokalny, a następnie porównuje odcisk palca. Jeśli istnieje różnica, dokonuje się porównaniaupdatedAt
. Jeśli są zbyt blisko, aby zadzwonić, wówczas trzeba będzie podjąć decyzję o pobraniu w oparciu o drugi węzeł (być może jest to ważniejsze) lub o przepchnięciu do drugiego węzła (ten węzeł jest ważniejszy). Jeśli zdalny zasób nie jest obecny lokalnie, wprowadzany jest wpis wypychany (zawiera on rzeczywiste dane do wstawienia / aktualizacji). Zakłada się, że wszelkie zasoby lokalne nieobecne w zdalnym dzienniku transakcji pozostają niezmienione.Żądania ściągania są wysyłane do zdalnego węzła, aby dane istniały lokalnie przy użyciu
itemURI
. Nie są stosowane lokalnie do później.Krok 3 - Wciśnij dziennik transakcji synchronizacji lokalnej do zdalnego
Lokalny:
PUT /remotehost/items/transactions
z treścią zawierającą dziennik transakcji synchronizacji lokalnej.Węzeł zdalny może przetwarzać to synchronicznie (jeśli jest mały i szybki) lub asynchronicznie (pomyśl 202 ZAAKCEPTOWANO ), jeśli może to spowodować znaczne obciążenie. Zakładając synchroniczną operację, wynik będzie wynosił 200 OK lub 409 KONFLIKT, w zależności od powodzenia lub niepowodzenia. W przypadku KONFLIKTU 409 proces musi zostać ponownie uruchomiony, ponieważ w zdalnym węźle wystąpił optymistyczny błąd blokowania (ktoś zmienił dane podczas synchronizacji). Zdalne aktualizacje są przetwarzane w ramach własnej transakcji aplikacji.
Krok 4 - Zaktualizuj lokalnie
Dane pobrane w kroku 2 są stosowane lokalnie w ramach transakcji aplikacji.
Chociaż powyższe nie jest idealne (istnieje kilka sytuacji, w których lokalny i zdalny może wpaść w kłopoty, a zdalne pobieranie danych z lokalnego jest prawdopodobnie bardziej wydajne niż umieszczanie go w dużym PUT), pokazuje jednak, w jaki sposób można użyć REST podczas bi- proces synchronizacji kierunkowej.
źródło
Rozważę operację synchronizacji jako zasób, do którego można uzyskać dostęp (GET) lub utworzyć (POST). Mając to na uwadze, adres URL interfejsu API może być:
(Nazywając to „synchronizacją”, a nie „synchronizacją”, aby było jasne, że nie jest to czasownik)
Następnie wykonaj:
Aby zainicjować synchronizację. Ponieważ operacja synchronizacji jest zasobem, to wywołanie może potencjalnie zwrócić identyfikator, którego można następnie użyć do sprawdzenia statusu operacji:
źródło
To trudny problem. Nie sądzę, aby REST był odpowiednim poziomem do wdrożenia synchronizacji. Solidna synchronizacja musiałaby zasadniczo być transakcją rozproszoną. REST nie jest narzędziem do tego zadania.
(Założenie: przez „synchronizację” sugerujesz, że jeden zasób może się zmienić niezależnie od drugiego w dowolnym momencie i chcesz mieć możliwość wyrównywania ich bez utraty aktualizacji.)
Możesz rozważyć ustawienie jednego z nich jako „głównego”, a drugiego „podrzędnego”, abyś mógł pewnie okresowo blokować dane podrzędne danymi nadrzędnymi.
Możesz również rozważyć Microsoft Sync Framework, jeśli absolutnie potrzebujesz obsługi niezależnie zmieniających się magazynów danych. To nie działałoby przez REST, ale za kulisami.
źródło
Apache CouchDB to baza danych oparta na REST, HTTP i JSON. Programiści wykonują podstawowe operacje CRUD przez HTTP. Zapewnia również mechanizm replikacji, który jest peer-to-peer przy użyciu tylko metod HTTP.
Aby zapewnić tę replikację, CouchDB musi mieć pewne konwencje specyficzne dla CouchDB. Żadne z nich nie jest przeciwne REST. Zapewnia każdemu dokumentowi (który jest zasobem REST w bazie danych) numer wersji . Jest to część reprezentacji JSON tego dokumentu, ale znajduje się również w nagłówku HTTP ETag. Każda baza danych ma również numer sekwencyjny, który umożliwia śledzenie zmian w bazie danych jako całości.
W celu rozwiązania konfliktu po prostu zauważają, że dokument jest w konflikcie, i zachowują wersje będące w konflikcie, pozostawiając go programistom korzystającym z bazy danych w celu zapewnienia algorytmu rozwiązywania konfliktów.
Możesz użyć CouchDB jako interfejsu API REST, który zapewni synchronizację po wyjęciu z pudełka, lub przyjrzyj się, w jaki sposób zapewnia replikację, aby zapewnić punkt wyjścia do stworzenia własnego algorytmu.
źródło
Możesz rozwiązać problem „czasowniki są złe” za pomocą prostej zmiany nazwy - użyj „aktualizacji” zamiast „synchronizacji”.
Proces synchronizacji faktycznie wysyła listę lokalnych aktualizacji wykonanych od ostatniej synchronizacji i odbiera listę aktualizacji wykonanych na serwerze w tym samym czasie.
źródło