Contexto
Devido à falta de estado do estilo de arquitetura REST, cada uma das solicitações fica completamente sozinha, levando o servidor a nunca armazenar informações sobre o cliente.
Portanto, o controle de simultaneidade pessimista não é adequado porque exigiria que o servidor armazene qual cliente obtém o bloqueio em um recurso. O controle de concorrência otimista é então usado, com a ajuda do Etag
cabeçalho. (btw, como eu pedi lá /programming/30080634/concurrency-in-a-rest-api )
Problema
O principal problema com um mecanismo de controle de concorrência otimista é que você permite o tempo todo, todos os clientes, executar quaisquer operações.
E eu gostaria de evitar isso sem violar o princípio da apatridia do REST. Quero dizer que todos os clientes não podem executar nenhuma operação a qualquer momento.
Questão
Na minha opinião, seria possível com um mecanismo de controle de concorrência semi-otimista , assim:
- Os clientes podem solicitar um token
- Somente um token pode ser gerado e tem um período de validade limitado
- Para executar operações em recursos (como POST ou PUT ), o cliente deve fornecer esse token como parte do corpo (ou cabeçalho?) Da solicitação. O cliente que não possui o token não pode executar essas operações.
É muito semelhante ao controle de concorrência otimista, exceto que apenas um cliente pode executar algumas operações (a que recebeu o token) ... ao contrário de "todos os clientes podem executar todas as operações".
Esse mecanismo é compatível com um estilo de arquitetura REST? Ele quebra alguma de suas restrições? Eu estava pensando em perguntar sobre SO, mas isso parece mais uma pergunta de alto nível, relacionada ao design de software.
fonte
Transaction
explicitamente como um Recurso.Etag
? SeEtag
você nunca tiver certeza de que suas operações serão concluídas, você poderá ter uma situação em que nunca executará nenhuma operação. Com uma trava, você tem certeza de pelo menos para executar sua operação. Portanto, ter um bloqueio simples é apenas o meio termo entre um ambiente em que "altos conflitos" e "raros conflitos" podem acontecer.Respostas:
Você nunca deve (como nunca NUNCA) bloquear qualquer recurso enquanto aguarda uma interação do usuário.
Em algum momento, alguns de seus usuários decolam por um longo fim de semana, deixando alguns registros vitais bloqueados.
Ah, mas você não permitirá que isso aconteça porque você tem algum esquema inteligente de resolução de tempo limite / impasse; então, em algum momento, isso ficará terrivelmente errado e um usuário que tenha recebido uma boa mensagem "seu widget foi solicitado" estará gritando no suporte técnico exigindo saber por que o widget não foi entregue.
A maioria das pessoas pode lidar com a mensagem "desculpe, outro usuário acabou de encomendar esta parte".
fonte
O uso de tokens é muito comum nas APIs, geralmente esses tokens são enviados como um cabeçalho e têm um ciclo de vida claro. Pense, por exemplo, em OAuth.
Independentemente da sua linguagem ou estrutura de programação, as APIs REST são semelhantes.
Posso pensar em vários cenários em que você deseja limitar a simultaneidade, dois deles são:
Vários clientes atualizando os mesmos recursos, como uma linha do banco de dados. Por exemplo: duas solicitações simultâneas, uma exclui um registro e a outra tenta atualizar o mesmo registro. Dependendo do seu banco de dados e de como você o configurou, é possível bloquear os registros ou a operação inválida, pois os dados serão diferentes ou não existirão.
Um superusuário ou administrador executando ações especiais com a API.
O que fazer nesses casos?
Use transações no banco de dados, singletons, bloqueios e mecanismos semelhantes para sincronizar o acesso aos recursos.
O token pode funcionar, acho que será melhor se você não armazenar informações sobre o cliente, apenas sobre o próprio token. Em uma etapa, você pode validar o usuário e atribuir o token. Apenas valide se o token está ativo e é válido. Use um token que pode ser descriptografado para obter informações extras. Você pode armazenar se esse é um token especial e permitir apenas por vez. Dessa forma, você valida o token, não o usuário.
Eu espero que isso ajude.
fonte
Somente o REST é muito primitivo, na verdade. Você pode iniciar o REST, mas, eventualmente, seu aplicativo avançado precisará de consultas com junções e atualizações com transações. Todo desenvolvedor que tenta adicionar essas coisas por conta própria seria propenso a erros e inconsistente. Felizmente, existe um padrão emergente chamado OData que faz exatamente isso. Ele se sobrepõe ao REST e fornece (1) linguagem de consulta que permite junções simples usando propriedades de navegação (sem a necessidade de expor chaves estrangeiras) e (2) processamento em lote que inclui conjuntos de alterações atômicas.
Consulte aqui (1) https://stackoverflow.com/a/3921423/471129 e,
Consulte aqui e (2) https://stackoverflow.com/a/21939972/471129
fonte