ver tweet sugerencias silenciar silenciadas palabras historial cuentas como busqueda borrar rest theory

rest - tweet - silenciar palabras en twitter



¿Por qué utilizar el enfoque de dos pasos para eliminar varios elementos con REST? (3)

Todos sabemos que la forma "estándar" de eliminar un solo elemento a través de REST es enviar una única solicitud DELETE a un URI example.com/Items/666 . Grandioso, vamos a seguir para eliminar muchos a la vez. Como no requerimos eliminación atómica (o transacción real, es decir, todo o nada), podemos simplemente decirle al cliente ''mala suerte, hacer muchas solicitudes'', pero eso no es muy bueno. Por lo tanto, necesitamos una manera de permitir que un cliente solicite que se eliminen muchos ''Artículos'' a la vez.

A mi entender, la solución "típica" a este problema es un enfoque de "dos pasos". Primero, el cliente envía una lista de ID de artículos y se le devuelve un URI como example.com/Items/Collection/1 . Una vez que se crea esa colección, llaman DELETE en ella.

Ahora, veo que esto funciona bien, excepto para mí, es una mala solución. En primer lugar, está obligando al cliente a realizar dos solicitudes para acomodar el servidor. En segundo lugar, "¿pensé que DELETE se suponía que debía eliminar un artículo?", No debería llamar a DELETE en este URI para cancelar la transacción de forma efectiva (aunque no es una transacción real), ¿cómo podríamos cancelarla? Realmente sería mejor si hubiera alguna forma de acción ''EJECUTAR'', pero no puedo mover tanto el bote. También obliga al servidor a tener en cuenta que "el JSON que se colocó por POST se parece más a una solicitud para modificar estos elementos, pero la solicitud fue BORRAR ... así que supongo que los eliminaré". Este enfoque también comienza a imponer una especie de estado en el cliente / servidor, no un estado verdadero que admito, pero es una especie de.

En mi opinión, una mejor solución sería llamar DELETE en example.com/Items (o quizás example.com/Items/Collection para sugerir que esto es un borrado múltiple) y pasar los datos JSON que contienen una lista de ID que desea borrar. Por lo que puedo ver, esto básicamente resuelve todos los problemas que tuvo el primer método. Es más fácil de usar como cliente, reduce el trabajo que tiene que hacer el servidor, es realmente sin estado, es más semántico.

Realmente agradecería la retroalimentación de esto, ¿me falta algo sobre REST que haga que mi solución a este problema sea poco realista? También agradecería los enlaces a los artículos, especialmente si comparan estos dos métodos; Soy consciente de que normalmente no está aprobado para SO. Necesito poder refutar que solo el primer método es realmente confiable, probar que el segundo enfoque es una solución viable. Por supuesto, si estoy ladrando al árbol equivocado, dímelo.


He pasado la última semana aproximadamente leyendo REST, y a mi entender, sería incorrecto describir cualquiera de estas soluciones como ''RESTfull'', más bien debería decir que ''ninguna solución va en contra de lo que REST medio''.

La respuesta corta es simplemente que REST, como se describe en la disertación de Roy Fielding (consulte el capítulo 5), no cubre el tema de cómo eliminar recursos, singular o múltiple, en una propiedad REST. Así es, no hay una ''manera correcta de eliminar un recurso'' ... bueno, no del todo.

REST en sí no define cómo eliminar un recurso, pero sí define que el protocolo que esté utilizando (recuerde que REST no es un protocolo) determinará cómo realizar estas acciones. El protocolo usualmente será HTTP; "usualmente" es la palabra clave como indica Fielding , REST no es sinónimo de HTTP.

Así que miramos a HTTP para decir qué método es "correcto". Lamentablemente, en lo que se refiere a HTTP, ambos enfoques son viables. Sí ''viable''. HTTP permitirá que un cliente envíe una solicitud POST con una carga útil (para crear un recurso de colección), y luego llame a un método DELETE en esta nueva colección para eliminar los recursos; También le permitirá enviar los datos dentro de la carga útil de un solo método DELETE para eliminar la lista de recursos. HTTP es simplemente el medio por el cual usted envía las solicitudes al servidor, le correspondería al servidor responder adecuadamente. Para mí, el protocolo HTTP parece ser bastante abierto a la interpretación en algunos lugares, pero parece establecer líneas de guía bastante claras sobre qué significan las acciones, cómo deben tratarse y qué respuesta debe darse; es solo que es un ''deberías hacer esto'' en lugar de ''debes hacer esto'', pero quizás estoy siendo un poco pedante en la redacción.

Algunas personas argumentan que el enfoque de "dos etapas" no puede ser "REST" ya que el servidor tiene que almacenar un "estado" para que el cliente realice la segunda acción. Esto es simplemente un malentendido de alguna parte. Debe entenderse que ni el cliente ni el servidor están almacenando ninguna información de ''estado'' sobre el otro entre la lista que se PUBLICÓ y luego se ELIMINÓ. Sí, la lista debe haberse creado antes de que se pueda eliminar, pero el servidor no recuerda que fue el cliente alfa el que hizo esta lista (tal enfoque permitiría al cliente simplemente llamar ''BORRAR'' como la próxima solicitud y el servidor recuerda para usar esa lista, esto no sería sin estado en absoluto) como tal, el cliente debe indicar al servidor que ELIMINE esa lista específica, la lista para la que recibió un URI específico. Si el cliente intentara BORRAR una lista de recopilación que aún no existía, simplemente se le diría "no se puede encontrar el recurso" (el error 404 clásico es más probable). Si desea afirmar que este enfoque de dos pasos mantiene un estado, también debe afirmar que para obtener simplemente un URI se requiere un estado, ya que el URI primero debe existir. Afirmar que existe la persistencia de este "estado" es una mala interpretación de lo que significa "estado". Y como una "prueba" adicional de que tal enfoque de dos etapas es realmente sin estado, es muy posible que el cliente alfa POSTE la lista y luego el cliente beta (sin haber tenido ninguna comunicación con el otro cliente) llame a DELETE en los recursos de la lista.

Creo que puede parecer bastante obvio que la segunda opción, de solo enviar la lista en la carga útil de la solicitud DELETE, es sin estado. Toda la información requerida para completar la solicitud se almacena completamente dentro de la solicitud.

Sin embargo, se podría argumentar que la acción DELETE solo debe invocarse en un recurso ''tangible'', pero al hacerlo, usted está ignorando descaradamente la parte de representación de REST; ¡Está en el nombre! Es el aspecto representativo que ''permite'' los URI como http://example.com/myService/timeNow , un URI que cuando ''got'' regresará, dinámicamente, a la hora actual, sin tener que cargar ningún archivo o leer desde alguna base de datos Es un concepto clave que los URI no se asignan directamente a algún dato ''tangible''.

Sin embargo, hay un aspecto de esa naturaleza sin estado que debe ser cuestionado. Como Fielding describe el ''cliente-servidor sin estado'' en la sección 5.1.3, afirma:

We next add a constraint to the client-server interaction: communication must be stateless in nature, as in the client-stateless-server (CSS) style of Section 3.4.3 (Figure 5-3), such that each request from client to server must contain all of the information necessary to understand the request, and cannot take advantage of any stored context on the server. Session state is therefore kept entirely on the client.

La parte clave aquí en mis ojos es "no puedo aprovechar ningún contexto almacenado en el servidor". Ahora les concedo que el ''contexto'' es algo abierto para la interpretación. Pero me resulta difícil ver cómo podría considerar el almacenamiento de una lista (ya sea en la memoria o en el disco) que se usará para dar un significado real útil que no violaría esta "regla". Sin este "contexto de lista", la operación DELETE no tiene sentido. Como tal, solo puedo concluir que hacer uso de un enfoque de dos pasos para realizar una acción como eliminar múltiples recursos no puede y no debe considerarse ''RESTfull''.

También envidio un tanto el esfuerzo que se ha tenido que hacer para encontrar argumentos para esto. Internet en general parece haberse arrastrado con esta idea. El enfoque de dos pasos es la manera "REST-lun" de realizar tales acciones, con el razonamiento "es la forma RESTfull de hacerlo". Si da un paso atrás por un momento respecto a lo que todos los demás están haciendo, verá que cualquiera de los dos enfoques requiere enviar la misma lista, por lo que puede ignorarse del argumento. Ambos enfoques son "representativos" y "sin estado". La única diferencia real es que, por alguna razón, un enfoque ha decidido requerir dos solicitudes. Estas dos solicitudes vienen luego con preguntas de seguimiento, como por ejemplo, "cuánto tiempo mantienes esos datos" y "cómo un cliente le dice a un servidor que ya no quiere que esta colección, pero desea conservar los recursos reales a los que se refiere ''.

Así que, hasta cierto punto, estoy respondiendo a mi pregunta con la misma pregunta: ''¿Por qué consideraría siquiera un enfoque de dos pasos?''


OMI:

HTTP BORRAR en la colección existente para eliminar todos sus miembros parece estar bien. Creando la colección solo para borrar todos los sonidos de miembros impares. Como usted mismo sugiera, simplemente pase los ID de los elementos que se eliminarán utilizando JSON (o cualquier otro formato de carga útil). Creo que el servidor debería intentar hacer varias eliminaciones de una transacción interna.


Yo diría que HTTP ya proporciona un método para eliminar múltiples elementos en forma de conexiones y canalizaciones persistentes . En el nivel del protocolo HTTP, es absolutamente correcto solicitar métodos idempotentes como DELETE de forma canalizada, es decir, enviar todas las solicitudes DELETE a la vez en una única conexión y esperar todas las respuestas.

Esto puede ser problemático para un cliente AJAX que se ejecuta en un navegador, ya que pocos navegadores tienen habilitada la compatibilidad con la canalización de manera predeterminada. Esto no es culpa de HTTP, sin embargo, es culpa de esos clientes específicos.