Imagine una aplicación web que almacena algunos recursos de datos con una identificación que almacena tres archivos adjuntos (por ejemplo, pdf) por dato.RESTful actualización atómica de múltiples recursos?
El esquema URL es
data/{id}/attachment1
data/{id}/attachment2
data/{id}/attachment3
Existe una API REST para los archivos adjuntos que proporcionan GET/PUT/DELETE operaciones de ejecución de las operaciones CRUD en el lado del servidor.
dejando que el ID sea 123, me gustaría para llevar a cabo una operación en la
- attachment1 se sustituye por un nuevo accesorio (de manera que
GET file/123/attachment1
devuelve el nuevo adjunto) se suprime - attachment2 (de tal manera que que
GET file/123/attachment2
devuelve 404) - attachment3 no se modifica.
La actualización debe ser atómica - la actualización completa se lleva a cabo por el servidor o nada en absoluto.
La aplicación de un simple PUT file/123/attachment1
y DELETE file/123/attachment2
no es atómica, ya que el cliente podría bloquearse después del PUT y el servidor no tiene ninguna pista de que debería realizar una reversión en este caso.
Entonces, ¿cómo implemento la operación de manera RESTful?
he pensado en dos soluciones, pero ambos no parecen estar al 100% REST:
- el uso del parche (se podría poner, pero PARCHE refleja mejor la semántica de una actualización parcial) con varias piezas/form-data on data/123: multipart/form-data es una secuencia de entidades que consiste en una nueva "aplicación/pdf" asociada con el campo "attachment1" y algo que representaría un valor nulo para indicar eliminación de attachment2.
Si bien esto garantiza la atomicidad, dudo que esto sea RESTful ya que sobrecargo el método PATCH usando diferentes listas de parámetros, lo que viola la restricción uniforme de la interfaz.
- Utilice un recurso que represente una transacción. Podría PUBLICAR el ID de datos 123 en una transacción-URL que crearía un recurso de transacción que representa una copia del estado actual del recurso de datos almacenado en el servidor, p. transacción/datos/123. Ahora puedo llamar a PUT y DELETE en los archivos adjuntos de este recurso temporal (por ejemplo,
DELETE transaction/data/123/attachment2
) y comunicar la confirmación de esta versión del recurso al servidor a través de un PUT en transaction/data/123. Esto garantiza la atomicidad mientras que tiene que implementar lógica adicional del lado del servidor para tratar con varios clientes cambiando el mismo recurso y clientes bloqueados que nunca se han comprometido.
Si bien esto parece ser coherente con REST, parece violar el inconveniente de la apatridia.El estado del recurso transaccional no es estado de servicio sino estado de aplicación, ya que cada recurso transaccional está asociado con un único cliente.
Estoy algo atrapado aquí, así que cualquier idea sería útil, ¡gracias!
El segundo enfoque tiene la ventaja de proporcionar un buen historial de cambios en los datos y puede permitirle saltear algunos registros. – Jasper
@mtsz Estoy luchando con este problema ahora mismo. Me gusta la respuesta que seleccionó a continuación, pero parece mucho trabajo crear un recurso de transacción con una vida corta y temporal. ¿Crees que sería malo darle a la transacción atómica un nombre como "switcheroo" y simplemente crear un servicio web específico que realice esa transacción? por ejemplo, POST/doSwitcheroo con un cuerpo de {archivo Id: 123} .... Este servicio tendría la lógica para realizar atómicamente las acciones que describiste arriba en el archivo con Id. 123 –