Suponiendo un sistema donde hay una aplicación web con un recurso y una referencia a una aplicación remota con otro recurso similar, ¿cómo representa una acción de sincronización bidireccional que sincroniza el recurso 'local' con el recurso 'remoto'?
Ejemplo:
Tengo una API que representa una lista de tareas pendientes.
GET / POST / PUT / DELETE / todos /, etc.
Esa API puede hacer referencia a servicios TODO remotos.
GET / POST / PUT / DELETE / todo_services /, etc.
Puedo manipular todos desde el servicio remoto a través de mi API como proxy a través de
GET / POST / PUT / DELETE / todo_services / abc123 /, etc.
Quiero la capacidad de hacer una sincronización bidireccional entre un conjunto local de todos y el conjunto remoto de TODOS.
De una manera rpc, uno podría hacer
POST / todo_services / abc123 / sync /
Pero, en la idea de "los verbos son malos", ¿hay una mejor manera de representar esta acción?
fuente
GET /todo/1/
yPOST
it to/todo_services/abc123/
Pero, la segunda forma: no estoy tomando un conjunto de datos y PONIÉNDOLO a un recurso, la acción que estoy tomando en realidad resulta en la modificación potencial de dos recursos. Supongo que podría recurrir a que las "sincronizaciones de todo" sean recursos en sí mismosPOST /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"}
Respuestas:
¿Dónde y cuáles son los recursos?
REST se trata de abordar los recursos de una manera apátrida y reconocible. No tiene que implementarse a través de HTTP, ni debe depender de JSON o XML, aunque se recomienda encarecidamente que se utilice un formato de datos hipermedia (consulte el principio HATEOAS ) ya que los enlaces y los identificadores son deseables.
Entonces, la pregunta es: ¿cómo se piensa acerca de la sincronización en términos de recursos?
¿Qué es la sincronización bidireccional? **
La sincronización bidireccional es el proceso de actualizar los recursos presentes en un gráfico de nodos para que, al final del proceso, todos los nodos hayan actualizado sus recursos de acuerdo con las reglas que rigen esos recursos. Normalmente, se entiende que todos los nodos tendrían la última versión de los recursos tal como está presente en el gráfico. En el caso más simple, el gráfico consta de dos nodos: local y remoto. Local inicia la sincronización.
Por lo tanto, el recurso clave que debe abordarse es un registro de transacciones y, por lo tanto, un proceso de sincronización podría verse así para la colección de "elementos" en HTTP:
Paso 1: Local recupera el registro de transacciones
Local:
GET /remotehost/items/transactions?earliest=2000-01-01T12:34:56.789Z
Remoto: 200 OK con el cuerpo que contiene el registro de transacciones que contiene campos similares a este.
itemId
- un UUID para proporcionar una clave primaria compartidaupdatedAt
- marca de tiempo para proporcionar un punto coordinado cuando los datos se actualizaron por última vez (suponiendo que no se requiere un historial de revisión)fingerprint
- un hash SHA1 del contenido de los datos para una comparación rápida si faltanupdateAt
unos segundositemURI
- un URI completo para el elemento para permitir la recuperación posteriorPaso 2: Local compara el registro de transacciones remotas con el suyo
Esta es la aplicación de las reglas comerciales de cómo sincronizar. Por lo general,
itemId
identificará el recurso local y luego comparará la huella digital. Si hay una diferencia, se hace una comparación deupdatedAt
. Si estos están demasiado cerca de la llamada, entonces se deberá tomar una decisión para extraer en función del otro nodo (tal vez sea más importante), o para empujar al otro nodo (este nodo es más importante). Si el recurso remoto no está presente localmente, se realiza una entrada de inserción (esta contiene los datos reales para insertar / actualizar). Se supone que los recursos locales que no están presentes en el registro de transacciones remotas no se modifican.Las solicitudes de extracción se realizan en el nodo remoto para que los datos existan localmente utilizando
itemURI
. No se aplican localmente hasta más tarde.Paso 3: empuje el registro de transacciones de sincronización local al control remoto
Local:
PUT /remotehost/items/transactions
con cuerpo que contiene el registro de transacciones de sincronización local.El nodo remoto podría procesar esto sincrónicamente (si es pequeño y rápido) o asincrónicamente (piense 202 ACEPTADO ) si es probable que incurra en una sobrecarga. Asumiendo una operación sincrónica, el resultado será 200 OK o 409 CONFLICT dependiendo del éxito o el fracaso. En el caso de un CONFLICTO 409 , entonces el proceso debe iniciarse nuevamente ya que ha habido un fallo de bloqueo optimista en el nodo remoto (alguien cambió los datos durante la sincronización). Las actualizaciones remotas se procesan bajo su propia transacción de aplicación.
Paso 4 - Actualiza localmente
Los datos extraídos en el Paso 2 se aplican localmente en una transacción de aplicación.
Si bien lo anterior no es perfecto (hay varias situaciones en las que lo local y lo remoto pueden tener problemas y tener datos remotos de extracción local es probablemente más eficiente que meterlo en un gran PUT), demuestra cómo REST puede usarse durante un bi- proceso de sincronización direccional.
fuente
Consideraría una operación de sincronización como un recurso al que se puede acceder (GET) o crear (POST). Con eso en mente, la URL de la API podría ser:
(Llamándolo "sincronización", no "sincronización" para dejar en claro que no es un verbo)
Entonces hazlo:
Para iniciar una sincronización. Dado que una operación de sincronización es un recurso, esta llamada podría devolver una identificación que luego puede usarse para verificar el estado de la operación:
fuente
Es este un problema difícil. No creo que REST sea un nivel apropiado para implementar la sincronización. Una sincronización robusta esencialmente necesitaría ser una transacción distribuida. REST no es la herramienta para ese trabajo.
(Supuesto: al "sincronizar" usted implica que cualquiera de los recursos puede cambiar independientemente del otro en cualquier momento, y desea la capacidad de realinearlos sin perder actualizaciones).
Es posible que desee considerar hacer que uno sea el "maestro" y el otro el "esclavo" para que pueda golpear al esclavo con confianza periódicamente con datos del maestro.
También es posible que desee considerar el Marco de sincronización de Microsoft si realmente necesita admitir el cambio independiente de los almacenes de datos. Esto no funcionaría a través de REST, sino detrás de escena.
fuente
Apache CouchDB es una base de datos basada en REST, HTTP y JSON. Los desarrolladores realizan operaciones CRUD básicas a través de HTTP. También proporciona un mecanismo de replicación que es de igual a igual utilizando solo métodos HTTP.
Para proporcionar esta replicación, CouchDB necesita tener algunas convenciones específicas de CouchDB. Ninguno de estos se opone a REST. Proporciona a cada documento (que es un recurso REST dentro de una base de datos) un número de revisión . Esto es parte de la representación JSON de ese documento, pero también está en el encabezado HTTP ETag. Cada base de datos también tiene un número de secuencia que permite realizar un seguimiento de los cambios en la base de datos en su conjunto.
Para la resolución de conflictos , simplemente notan que un documento está en conflicto y retienen las versiones en conflicto, dejándolo a los desarrolladores que usan la base de datos para proporcionar un algoritmo de resolución de conflictos.
Puede usar CouchDB como su API REST, que le dará sincronización de fábrica, o echar un vistazo a cómo proporciona la replicación para proporcionar un punto de partida para crear su propio algoritmo.
fuente
Puede resolver el problema de "los verbos son malos" con un cambio de nombre simple: use "actualizaciones" en lugar de "sincronización".
El proceso de sincronización en realidad está enviando una lista de actualizaciones locales realizadas desde la última sincronización y recibiendo una lista de actualizaciones realizadas en el servidor en ese mismo tiempo.
fuente