Supondo que um sistema em que haja um aplicativo Web com um recurso e uma referência a um aplicativo remoto com outro recurso semelhante, como você representa uma ação de sincronização bidirecional que sincroniza o recurso 'local' com o recurso 'remoto'?
Exemplo:
Eu tenho uma API que representa uma lista de tarefas.
GET / POST / PUT / DELETE / todos /, etc.
Essa API pode fazer referência a serviços remotos TODO.
GET / POST / PUT / DELETE / todo_services /, etc.
Eu posso manipular todos do serviço remoto através da minha API como proxy via
GET / POST / PUT / DELETE / todo_services / abc123 /, etc.
Quero a capacidade de fazer uma sincronização bidirecional entre um conjunto local de todos e o conjunto remoto de TODOS.
De uma maneira rpc, alguém poderia fazer
POST / todo_services / abc123 / sync /
Mas, na idéia "os verbos são ruins", existe uma maneira melhor de representar essa ação?
fonte
GET /todo/1/
ePOST
ela/todo_services/abc123/
, mas, a bidirecional - não estou pegando um conjunto de dados e colocando-o em um recurso, a ação que estou realizando realmente resulta na modificação potencial de dois recursos. Eu acho que eu poderia voltar a ter "todas as sincronizações" sendo recursos eles mesmosPOST /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"}
Respostas:
Onde e quais são os recursos?
O REST tem tudo a ver com endereçamento de recursos de maneira apátrida e detectável. Ele não precisa ser implementado por HTTP, nem deve depender de JSON ou XML, embora seja altamente recomendável que um formato de dados hipermídia seja usado (consulte o princípio HATEOAS ), pois os links e os IDs são desejáveis.
Então, a pergunta se torna: como alguém pensa em sincronização em termos de recursos?
O que é sincronização bidirecional? **
A sincronização bidirecional é o processo de atualização dos recursos presentes em um gráfico de nós, para que, no final do processo, todos os nós tenham atualizado seus recursos de acordo com as regras que regem esses recursos. Normalmente, entende-se que todos os nós teriam a versão mais recente dos recursos, conforme presente no gráfico. No caso mais simples, o gráfico consiste em dois nós: local e remoto. Local inicia a sincronização.
Portanto, o principal recurso que precisa ser endereçado é um log de transações e, portanto, um processo de sincronização pode ser assim para a coleção "items" em HTTP:
Etapa 1 - Local recupera o log de transações
Local:
GET /remotehost/items/transactions?earliest=2000-01-01T12:34:56.789Z
Remoto: 200 OK com o corpo contendo o log de transações contendo campos semelhantes a este.
itemId
- um UUID para fornecer uma chave primária compartilhadaupdatedAt
- carimbo de data / hora para fornecer um ponto coordenado quando os dados foram atualizados pela última vez (assumindo que um histórico de revisão não seja necessário)fingerprint
- um hash SHA1 do conteúdo dos dados para comparação rápida seupdateAt
houver alguns segundos foraitemURI
- um URI completo para o item para permitir a recuperação posteriorEtapa 2 - Local compara o log de transações remotas com seus próprios
Esta é a aplicação das regras de negócios de como sincronizar. Normalmente, o
itemId
identifica o recurso local e depois compara a impressão digital. Se houver uma diferença,updatedAt
é feita uma comparação de . Se estes estiverem muito perto de serem chamados, será necessário tomar uma decisão para puxar com base no outro nó (talvez seja mais importante) ou empurrar para o outro nó (este nó é mais importante). Se o recurso remoto não estiver presente localmente, será feita uma entrada push (ela contém os dados reais para inserção / atualização). Todos os recursos locais que não estão presentes no log de transações remotas são assumidos como inalterados.As solicitações pull são feitas no nó remoto para que os dados existam localmente usando o
itemURI
. Eles não são aplicados localmente até mais tarde.Etapa 3 - Enviar o log de transações de sincronização local para o remoto
Local:
PUT /remotehost/items/transactions
com o corpo que contém o log de transações de sincronização local.O nó remoto pode processar isso de forma síncrona (se for pequena e rápida) ou de forma assíncrona (pense 202 ACEITADO ) se for provável que ocorra muita sobrecarga. Supondo uma operação síncrona, o resultado será 200 OK ou 409 CONFLITO, dependendo do sucesso ou falha. No caso de um 409 CONFLICT , o processo deve ser iniciado novamente, pois houve uma falha de bloqueio otimista no nó remoto (alguém alterou os dados durante a sincronização). As atualizações remotas são processadas sob sua própria transação de aplicativo.
Etapa 4 - Atualize localmente
Os dados extraídos na Etapa 2 são aplicados localmente em uma transação de aplicativo.
Embora o exposto acima não seja perfeito (há várias situações em que local e remoto podem ter problemas e ter dados de extração remota do local é provavelmente mais eficiente do que colocá-lo em uma grande PUT), ele demonstra como o REST pode ser usado durante processo de sincronização direcional.
fonte
Eu consideraria uma operação de sincronização como um recurso que pode ser acessado (GET) ou criado (POST). Com isso em mente, o URL da API pode ser:
(Chamando de "sincronização", não de "sincronização" para deixar claro que não é um verbo)
Então faça:
Para iniciar uma sincronização. Como uma operação de sincronização é um recurso, essa chamada pode retornar um ID que pode ser usado para verificar o status da operação:
fonte
Este é um problema díficil. Não acredito que o REST seja um nível apropriado para implementar a sincronização. Uma sincronização robusta precisaria essencialmente ser uma transação distribuída. O REST não é a ferramenta para esse trabalho.
(Suposição: por "sincronização", você está sugerindo que um dos recursos pode mudar independentemente do outro a qualquer momento e deseja realinhar os recursos sem perder as atualizações.)
Você pode considerar tornar um o "mestre" e o outro o "escravo", para poder confundir o escravo com confiança periodicamente com os dados do mestre.
Você também pode considerar o Microsoft Sync Framework se precisar absolutamente oferecer suporte a repositórios de dados com alterações independentes. Isso não funcionaria no REST, mas nos bastidores.
fonte
O Apache CouchDB é um banco de dados baseado em REST, HTTP e JSON. Os desenvolvedores realizam operações básicas de CRUD sobre HTTP. Ele também fornece um mecanismo de replicação ponto a ponto usando apenas métodos HTTP.
Para fornecer essa replicação, o CouchDB precisa ter algumas convenções específicas do CouchDB. Nada disso se opõe ao REST. Ele fornece a cada documento (que é um recurso REST dentro de um banco de dados) um número de revisão . Isso faz parte da representação JSON desse documento, mas também está no cabeçalho HTTP ETag. Cada banco de dados também possui um número de sequência que permite rastrear alterações no banco de dados como um todo.
Para resolução de conflitos , eles simplesmente observam que um documento está em conflito e mantém as versões em conflito, deixando para os desenvolvedores que usam o banco de dados para fornecer um algoritmo de resolução de conflitos.
Você pode usar o CouchDB como sua API REST, que fornecerá a sincronização imediata ou verificar como ele fornece replicação para fornecer um ponto de partida para criar seu próprio algoritmo.
fonte
Você pode resolver o problema "os verbos são ruins" com uma simples renomeação - use "updates" em vez de "sync".
O processo de sincronização está realmente enviando uma lista de atualizações locais feitas desde a última sincronização e recebendo uma lista de atualizações feitas no servidor no mesmo tempo.
fonte