Dove e quali sono le risorse?
REST si basa sull'indirizzamento delle risorse in modo stateless e rilevabile. Non deve essere implementato su HTTP, né deve fare affidamento su JSON o XML, sebbene sia strongmente raccomandato l'uso di un formato di dati ipermediali (vedere HATEOAS principio) poiché i collegamenti e gli ID sono desiderabili.
Quindi, la domanda diventa: come si può pensare alla sincronizzazione in termini di risorse?
Che cos'è la sincronizzazione bidirezionale? **
La sincronizzazione bidirezionale è il processo di aggiornamento delle risorse presenti su un grafico di nodi in modo che, alla fine del processo, tutti i nodi abbiano aggiornato le proprie risorse in conformità con le regole che governano tali risorse. In genere, si intende che tutti i nodi abbiano l'ultima versione delle risorse presente nel grafico. Nel caso più semplice il grafico è costituito da due nodi: locale e remoto. Local avvia la sincronizzazione.
Quindi la risorsa chiave che deve essere indirizzata è un log delle transazioni e, pertanto, un processo di sincronizzazione potrebbe essere simile alla raccolta "items" sotto HTTP:
Passaggio 1 - Local recupera il log delle transazioni
Locale: GET /remotehost/items/transactions?earliest=2000-01-01T12:34:56.789Z
Remoto: 200 OK con il corpo contenente il log delle transazioni contenente campi simili a questo.
-
itemId
- un UUID per fornire una chiave primaria condivisa
-
updatedAt
- timestamp per fornire un punto coordinato al momento dell'ultimo aggiornamento dei dati (presupponendo che non sia richiesta una cronologia delle revisioni)
-
fingerprint
- un hash SHA1 del contenuto dei dati per un confronto rapido se updateAt
è pochi secondi fuori
-
itemURI
- un URI completo dell'elemento per consentire il recupero più tardi
Passaggio 2: locale confronta il registro delle transazioni remote con il proprio
Questa è l'applicazione delle regole aziendali di come sincronizzare. In genere, itemId
identifica la risorsa locale, quindi confronta l'impronta digitale. Se c'è una differenza, viene eseguito un confronto di updatedAt
. Se questi sono troppo vicini, è necessario prendere una decisione per eseguire il pull in base all'altro nodo (forse è più importante) o per passare all'altro nodo (questo nodo è più importante). Se la risorsa remota non è presente localmente, viene effettuata una immissione push (che contiene i dati effettivi per inserimento / aggiornamento). Si presume che tutte le risorse locali non presenti nel log delle transazioni remote siano invariate.
Le richieste pull vengono eseguite sul nodo remoto in modo che i dati esistano localmente utilizzando itemURI
. Non vengono applicati localmente fino a un momento successivo.
Passaggio 3: invio del log delle transazioni di sincronizzazione locale su remoto
Locale: PUT /remotehost/items/transactions
con il corpo contenente il log delle transazioni di sincronizzazione locale.
Il nodo remoto potrebbe elaborarlo in modo sincrono (se è piccolo e veloce) o in modo asincrono (pensa 202 ACCETTATO ) se è probabile che si verifichi un sovraccarico. Assumendo un'operazione sincrona, il risultato sarà 200 OK o 409 CONFLICT a seconda del successo o dell'errore. Nel caso di un 409 CONFLICT , il processo deve essere riavviato poiché si è verificato un errore di blocco ottimistico sul nodo remoto (qualcuno ha modificato i dati durante la sincronizzazione). Gli aggiornamenti remoti vengono elaborati con la propria transazione applicativa.
Passaggio 4: aggiornamento locale
I dati estratti nel passaggio 2 vengono applicati localmente in una transazione di applicazione.
Sebbene quanto sopra non sia perfetto (ci sono diverse situazioni in cui locali e remote possono mettersi nei guai e avere dati di pull remoti da locali è probabilmente più efficiente che inserirli in un grosso PUT) dimostra come REST può essere usato durante un processo di sincronizzazione bidirezionale.