Me he encontrado con este mismo problema una y otra vez y no he encontrado una solución que realmente me pareció óptima.
Digamos que en una aplicación, tiene una lista ordenada y deja que el usuario cambie ese orden arrastrando y soltando o algo así. Desea que los cambios en el orden persistan. ¿Cómo modelas eso?
¿Cómo debo diseñar un servicio reparador de un recurso de lista ordenada?
En particular, ¿cómo debería diseñar el list
y item
modelar de un recurso de descanso? El diseño más común que he visto es la item
entidad que tiene una order
o position
propiedad. Otro enfoque que he escuchado es una lista doblemente vinculada en los artículos.
¿Qué enfoque no escribe demasiado en la base de datos y generalmente es rápido de actualizar y leer para los clientes? ¿Cómo se deben exponer los puntos finales?
fuente
Respuestas:
Representar una lista ordenada es uno de los problemas difíciles con las bases de datos relacionales. Agregar una propiedad de posición a la relación lista-membresía es la forma más común de hacerlo, ya que puede recuperar fácilmente la lista ordenada agregando
ORDER BY position
a su consulta SQL, y porque puede insertar fácilmente elementos en el medio de la lista promediando el valores del miembro de la lista anterior y posterior, suponiendo que la posición es flotante en lugar de entero.Se debe evitar el uso de listas doblemente vinculadas, ya que es fácil hacer que los enlaces sean inconsistentes accidentalmente y terminar con un gráfico o árbol cíclico.
Sin embargo, las API RESTful no sufren las restricciones de las bases de datos relacionales. Puedes hacer algo que se siente natural, en lugar de usar un truco como una propiedad de posición.
Si solo tiene unos pocos cientos de elementos en la lista, simplemente transfiera la lista completa en una solicitud. Suponiendo que queremos reordenar
[1, 2, 3, 4]
donde los miembros de la lista son ID, podríamosEl backend puede traducir esto a cualquier tecnología de base de datos que esté utilizando, pero el usuario de la API no tiene que considerar estos detalles.
Si la lista es grande y los artículos generalmente se solicitarían individualmente, puede permitir un índice en la URL:
Si está interesado en HATEOAS, la respuesta puede incluir enlaces prev / next para simplificar la navegación, si el recurso generalmente se consumiría así. Sin embargo, esto no implica necesariamente que su base de datos también contenga esta lista doblemente vinculada.
Si la lista es muy grande, es posible que desee exponer
ArrayList
operaciones similares comoinsert
opush
/append
. Podría imaginar una llamada comoSi el reordenamiento es un caso de uso común y el reordenamiento debe confirmarse de inmediato, entonces podría ofrecer un punto final apropiado en su API:
Si la lista reordenada debe confirmarse explícitamente, será más fácil transferir el nuevo pedido como un documento JSON, ver arriba.
Ahora no es del todo cierto que pueda ver su API completamente separada de la tecnología de base de datos que está utilizando. Sin embargo, es mejor mantener la API externa lo más libre posible de los detalles de implementación. Si alguna reordenación toca unas 30 filas solo para actualizar una columna de orden de enteros, no es gran cosa. Simplemente haga lo más simple posible y actualice siempre la lista completa. Si su báscula requiere que el uso de su base de datos sea más sofisticado, prefiera capturar esta sofisticación en el backend, donde es más fácil mantener la coherencia.
fuente
Creo que la viabilidad de los diferentes enfoques depende en gran medida de la base de datos subyacente que se utilice.
Este enfoque sugiere mover un elemento en el pedido:
Eso puede estar sujeto a condiciones de carrera a menos que tenga transaccionalidad SERIALIZABLE. ¡El nivel predeterminado de READ_COMMITTED en la mayoría de los DB no eliminará una condición de carrera!
De hecho, creo que en la mayoría de los casos, siempre que la lista sea relativamente pequeña, el enfoque de reemplazar la lista completa tiene menos problemas con las condiciones de carrera y no puede corromper los datos. Si el conjunto de elementos ha cambiado desde que el cliente realizó la solicitud, puede devolver un 409 (Conflicto).
Sufre de últimas victorias de escritura, pero eso es cierto, literalmente, de CUALQUIER API. No importa qué API esté implementando, otro cliente puede haber actualizado la cosa mientras está viendo una página.
fuente