Encontrei esse mesmo problema repetidamente e não encontrei uma solução que realmente considerasse ideal.
Digamos que em um aplicativo, você tenha uma lista ordenada e permita que o usuário altere essa ordem arrastando e soltando ou algo assim. Você deseja que as alterações na ordem persistam. Como você modela isso?
Como devo projetar um serviço reparador de um recurso de lista ordenada?
Em particular, como devo projetar list
e item
modelar um recurso repousante? O design mais comum que eu já vi é a item
entidade que possui uma propriedade order
ou position
. Outra abordagem que ouvi é uma lista duplamente vinculada dos itens.
O que é uma abordagem que não grava muito no banco de dados e geralmente é rápida de atualizar e ler para os clientes? Como os pontos de extremidade devem ser expostos?
fonte
Respostas:
Representar uma lista ordenada é um dos problemas difíceis nos bancos de dados relacionais. Adicionar uma propriedade position à relação lista-associação é a maneira mais comum de fazer isso, pois você pode recuperar facilmente a lista ordenada adicionando
ORDER BY position
à sua consulta SQL e porque é possível inserir itens facilmente no meio da lista calculando a média do valores do membro da lista anterior e subseqüente, assumindo que a posição é um ponto flutuante em vez de inteiro.O uso de listas duplamente vinculadas deve ser evitado, pois é fácil acidentalmente tornar os links inconsistentes e terminar com um gráfico ou árvore cíclica.
No entanto, as APIs RESTful não sofrem com as restrições dos bancos de dados relacionais. Você pode simplesmente fazer algo que pareça natural, em vez de usar um hack como uma propriedade position.
Se você tiver apenas algumas centenas de elementos na lista, basta transferir a lista inteira em uma solicitação. Supondo que queremos reorganizar
[1, 2, 3, 4]
onde os membros da lista são IDs, poderíamosO back-end pode traduzi-lo para qualquer tecnologia de banco de dados que você estiver usando, mas o usuário da API não precisa considerar esses detalhes.
Se a lista for grande e os itens geralmente forem solicitados individualmente, você poderá permitir um índice no URL:
Se você gosta do HATEOAS, a resposta pode incluir links anteriores / próximos para simplificar a navegação, se o recurso normalmente for consumido dessa maneira. No entanto, isso não significa que seu banco de dados também contenha essa lista duplamente vinculada.
Se a lista for muito grande, convém expor
ArrayList
operações do tipo comoinsert
oupush
/append
. Eu poderia imaginar uma ligação comoSe a reordenação for um caso de uso comum e a reordenação for confirmada imediatamente, você poderá oferecer um ponto de extremidade apropriado em sua API:
Se a lista reordenada deve ser confirmada explicitamente, será mais fácil transferir o novo pedido como um documento JSON, veja acima.
Agora não é bem verdade que você pode ver sua API completamente separada da tecnologia de banco de dados que está usando. No entanto, é melhor manter a API externa o mais livre possível dos detalhes da implementação. Se alguma reordenação tocar cerca de 30 linhas apenas para atualizar uma coluna de pedido inteiro, isso não é grande coisa. Basta fazer a coisa mais simples possível e sempre atualizar a lista inteira. Se sua escala exigir que o uso do banco de dados seja mais sofisticado, prefira capturar essa sofisticação no back-end, onde é mais fácil manter a consistência.
fonte
Eu acho que a viabilidade de diferentes abordagens depende muito do banco de dados subjacente que está sendo usado.
Essa abordagem sugeriu mover um item na ordem:
Isso pode estar sujeito a condições de corrida, a menos que você tenha transacionalidade SERIALIZÁVEL. O nível padrão de READ_COMMITTED na maioria dos bancos de dados não eliminará uma condição de corrida!
Na verdade, eu acho que, na maioria dos casos - desde que a lista seja relativamente pequena -, a abordagem de substituir a lista completa tem menos problemas com as condições de corrida e não pode corromper os dados. Se o conjunto de itens tiver sido alterado desde que o cliente fez a solicitação, você poderá retornar um 409 (Conflito).
Ele sofre de last-write-wins, mas isso é verdade para literalmente QUALQUER API. Independentemente da API que você está implementando, outro cliente pode ter atualizado a coisa enquanto você visualiza uma página.
fonte