Eu acho que você pode ter um processo de usuário para incompatibilidade de implementação aqui.
Primeiro: um usuário honestamente deseja executar várias alterações em um arquivo simultaneamente? Uma renomeação (que pode ou não incluir uma mudança de caminho?), Mudança de propriedade e talvez alteração do conteúdo do arquivo (por uma questão de argumento) parecem ações separadas.
Vamos considerar o caso em que a resposta é "sim" - seus usuários realmente desejam fazer essas alterações simultaneamente.
Nesse caso, eu recomendo fortemente contra qualquer implementação que envia vários eventos - RenameFileCommand
, MoveFileCommand
, ChangeOwnerCommand
- para representar essa única intenção do usuário.
Por quê? Porque os eventos podem falhar. Talvez seja extremamente raro, mas seu usuário enviou uma operação que parecia atômica - se um dos eventos posteriores falhar, o estado do seu aplicativo agora é inválido.
Você também está convidando riscos de corrida em um recurso claramente compartilhado entre cada um dos manipuladores de eventos. Você precisará escrever "ChangeOwnerCommand" de forma que o nome e o caminho do arquivo não importem, pois podem estar desatualizados no momento em que o comando é recebido.
Ao implementar um sistema tranqüilo não orientado a eventos com arquivos em movimento e renomear, prefiro garantir consistência usando algo como um sistema eTag - verifique se a versão do recurso que está sendo editado é a versão que o usuário recuperou pela última vez e falha se foi modificado desde então. Mas se você estiver despachando vários comandos para esta operação de usuário único, precisará incrementar a versão do recurso após cada comando - para que você não tenha como saber que o recurso que o usuário está editando é realmente a mesma versão do recurso que foi lido pela última vez .
O que quero dizer com isso é - e se outra pessoa executar outra operação no arquivo quase ao mesmo tempo. Os 6 comandos podem ser empilhados em qualquer ordem. Se tivéssemos apenas 2 comandos atômicos, o comando anterior poderia ter sucesso e o comando posterior poderia falhar "o recurso foi modificado desde a última vez que foi recuperado". Mas não há proteção contra isso quando os comandos não são atômicos, portanto a consistência do sistema é violada.
Curiosamente, existe um movimento em direção a algo como a arquitetura baseada em eventos no REST, chamada "Descansar sem PUT", recomendada no radar da tecnologia Thoughtworks, janeiro de 2015 . Há um blog consideravelmente mais longo sobre o Rest without PUT aqui .
Essencialmente, a idéia é que POST, PUT, DELETE e GET sejam adequados para aplicativos pequenos, mas quando você precisar começar a supor que a colocação, a postagem e a exclusão podem ser interpretadas na outra extremidade, você introduz o acoplamento. (por exemplo, "quando EXCLUIR o recurso associado à minha conta bancária, a conta deve ser fechada") E a solução proposta é tratar o REST de uma maneira mais originada por evento. Permite POST a intenção do usuário como um único recurso de evento.
O outro caso é mais simples. Se seus usuários não quiserem executar todas essas operações simultaneamente, não permita. POST um evento para cada intenção do usuário. Agora você pode usar o etag versioning em seus recursos.
Quanto aos outros aplicativos que estão usando uma API muito diferente dos seus recursos. Isso cheira a problemas. Você pode construir uma fachada da API antiga em cima da API RESTful e apontá-las para a fachada? expor um serviço que executa várias atualizações em um arquivo em sequência através do servidor REST?
Se você não criar a interface RESTful na parte superior da solução antiga, nem construir uma fachada da interface antiga na parte superior da solução REST e tentar manter as duas APIs apontando para um recurso de dados compartilhado, ocorrerá grandes dores de cabeça.