¿REST DELETE es realmente idempotente?

166

Suprimir se supone que es idempotente.

Si ELIMINO http://example.com/account/123 eliminará la cuenta.

Si lo vuelvo a hacer, ¿esperaría un 404, ya que la cuenta ya no existe? ¿Qué sucede si intento ELIMINAR una cuenta que nunca existió?

Ben Noland
fuente
11
Además de las respuestas, sugeriría no centrarse demasiado en la característica idempotente en general: no dice nada sobre la conmutatividad y las solicitudes concurrentes. Por ejemplo, N + 1 de la misma solicitud PUT "R1" debería tener el mismo efecto, pero no sabe si otro cliente realizó una solicitud PUT / DELETE "R2" diferente entre las suyas, por lo tanto, mientras n R1 = R1 ym R2 = R2, algo en lo que se entrelazan las solicitudes "R1" y "R2" no necesariamente "parecerán" idempotentes si solo toma la perspectiva de un solo cliente.
Bruno

Respuestas:

188

Idempotencia se refiere al estado del sistema después de que la solicitud se haya completado.


En todos los casos (aparte de los problemas de error, ver más abajo), la cuenta ya no existe.

Desde aqui

"Los métodos también pueden tener la propiedad de" idempotencia "en que ( además de los problemas de error o caducidad ) los efectos secundarios de N> 0 solicitudes idénticas son los mismos que para una sola solicitud. Los métodos GET, HEAD, PUT y DELETE comparten esta propiedad. Además, los métodos OPTIONS y TRACE NO DEBEN tener efectos secundarios, por lo que son inherentemente idempotentes ".


El bit clave es que los efectos secundarios de N> 0 solicitudes idénticas son las mismas que para una sola solicitud.

Sería correcto esperar que el código de estado sería diferente, pero esto no afecta el concepto central de idempotencia: puede enviar la solicitud más de una vez sin cambios adicionales en el estado del servidor.

Chris McCauley
fuente
3
Efectos secundarios! == estado del servidor
wprl
2
@wprl Existe un debate sobre qué es realmente este "efecto secundario". Puede ser "estado del servidor" o puede ser una respuesta enviada al cliente. leedavis81.github.io/is-a-http-delete-requests-idempotent
Alireza
Aquí hay un argumento de que 404 en un segundo DELETE puede cambiar el estado del servidor: stackoverflow.com/a/45194747/317522
Paulo Merson
1
@PauloMerson Gracias, personalmente no creo que importe si la segunda devolución es 404 o 200, el estado del servidor no ha cambiado, así que estoy contento con eso.
Chris McCauley
46

Idempotent es sobre el efecto de la solicitud, no sobre el código de respuesta que obtienes.

http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.1.2 dice:

Los métodos también pueden tener la propiedad de "idempotencia" en que (aparte de los problemas de error o caducidad) los efectos secundarios de N> 0 solicitudes idénticas son las mismas que para una solicitud única.

Si bien puede obtener un código de respuesta diferente, el efecto del envío de solicitudes DELETE N + 1 al mismo recurso puede considerarse el mismo.

Bruno
fuente
13

La distinción importante es que idempotente se refiere a los efectos secundarios , no a todos los efectos o respuestas. Si lo hace DELETE http://example.com/account/123, el efecto es que la cuenta 123 ahora se elimina del servidor. Ese es el único efecto, el único cambio al estado del servidor. Ahora digamos que DELETE http://example.com/account/123vuelve a hacer la misma solicitud, el servidor responderá de manera diferente, pero su estado es el mismo.

No es como si la solicitud DELETE hubiera decidido cambiar el estado del servidor de una manera diferente porque faltaba la cuenta, como eliminar otra cuenta o dejar un registro de errores. No, puede llamar a la misma solicitud DELETE un millón de veces y puede estar seguro de que el servidor está en el mismo estado que estaba la primera vez que lo llamó .

Janac Meena
fuente
7

Desde el HTTP RFC :

Los métodos también pueden tener la propiedad de "idempotencia" en que (aparte de los problemas de error o caducidad) los efectos secundarios de N> 0 solicitudes idénticas son las mismas que para una solicitud única.

Tenga en cuenta que eso es "efectos secundarios", no "respuesta".

fumanchu
fuente
7

Si. Independientemente del código de respuesta.

Desde el último RFC para HTTP 1.1 (énfasis mío):

Los métodos idempotentes se distinguen porque la solicitud puede repetirse automáticamente si ocurre una falla de comunicación antes de que el cliente pueda leer la respuesta del servidor. Por ejemplo, si un cliente envía una solicitud PUT y la conexión subyacente se cierra antes de recibir cualquier respuesta, el cliente puede establecer una nueva conexión y volver a intentar la solicitud idempotente. Sabe que repetir la solicitud tendrá el mismo efecto deseado, incluso si la solicitud original tuvo éxito, aunque la respuesta puede ser diferente.

Dice explícitamente que la respuesta puede diferir. Más importante aún, señala la razón del concepto: si una acción es idempotente, el cliente puede repetir la acción cuando encuentra algún error, y sabe que no se bloqueará nada al hacerlo; de lo contrario, el cliente deberá realizar una consulta adicional (posiblemente GET) para ver si la anterior es efectiva, antes de repetir la acción de manera segura. Mientras el servidor pueda hacer tal garantía, la acción es idempotente. Cita de otro comentario :

La idempotencia informática se trata de la solidez de un sistema. Dado que las cosas pueden fallar (por ejemplo, corte de red), cuando se detecta una falla, ¿cómo se recupera? La recuperación más fácil es volver a hacerlo, pero eso solo funciona si hacerlo de nuevo es idempotente. Por ejemplo, discard(x)es idempotente, pero pop()no lo es. Se trata de recuperación de errores.

Franklin Yu
fuente
2

Creo que lo mismo, 404: la cuenta no existe.

Podrías argumentar 400 - Mala solicitud. Pero en el sentido de REST, el objeto sobre el que solicitó realizar una acción no existe. Eso se traduce en 404.

Jason McCreary
fuente
1
Para generar un 400 tendrías que saber que el objeto solía existir, lo cual es muy inquieto.
annakata
1
@annakata, 400 ni siquiera es para recursos que solían existir (quizás tenga 410 / Gone en mente), es para solicitudes incorrectas "El servidor no pudo entender la solicitud debido a una sintaxis incorrecta".
Bruno
3
@ Bruno: Soy consciente de lo que significa, el OP lo citó.
annakata
1
Creo que 200 estaría bien. Desea que el estado del servidor sea que la cuenta se ha ido. ¿Importa qué solicitud realmente hizo que desapareciera? Todavía se ha ido en la segunda solicitud, el estado del servidor no ha cambiado.
Andy
2

Citado de mi otra respuesta aquí :

Históricamente, RFC 2616, publicado en 1999, era la especificación HTTP 1.1 más referenciada. Lamentablemente, su descripción sobre la idempotencia fue vaga , lo que deja espacio para todos estos debates. Pero esas especificaciones han sido reemplazadas por RFC 7231. Citado de RFC 7231, sección 4.2.2 Métodos idempotentes , énfasis mío:

Un método de solicitud se considera "idempotente" si el EFECTO pretendido en el servidor de múltiples solicitudes idénticas con ese método es el mismo que el efecto de una sola solicitud de este tipo. De los métodos de solicitud definidos por esta especificación, PUT, DELETE y los métodos de solicitud seguros son idempotentes .

Entonces, está escrito en las especificaciones, la idempotencia se trata del efecto en el servidor. El primer DELETE que devuelve un 204 y luego el DELETE posterior que devuelve 404, un código de estado diferente NO hace que el DELETE sea no idempotente. Usar este argumento para justificar un retorno 204 posterior es simplemente irrelevante.


OK, entonces no se trata de idempotencia. Pero entonces una pregunta de seguimiento puede ser, ¿qué pasa si todavía elegimos usar 204 en la SUPRIMACIÓN posterior? ¿Está bien?

Buena pregunta. La motivación es comprensible: permitir que el cliente alcance el resultado deseado, sin preocuparse por el manejo de errores. Yo diría que devolver 204 en DELETE posterior, es una "mentira piadosa" del lado del servidor en gran parte inofensiva, que el lado del cliente no notará inmediatamente una diferencia. Es por eso que hay personas haciendo eso en la naturaleza y todavía funciona. Solo tenga en cuenta que dicha mentira puede considerarse semánticamente extraña, porque "GET / non-exist" devuelve 404 pero "DELETE / non-exist" da 204, en ese momento el cliente descubriría que su servicio no cumple completamente sección 6.5.4 404 no encontrado .

Pero entonces, la forma prevista insinuada por RFC 7231, es decir, devolver 404 en la ELIMINACIÓN posterior, no debería ser un problema en primer lugar. Muchos más desarrolladores optaron por hacer eso. Probablemente se deba a que cualquier cliente que implemente HTTP DELETE (o cualquier método HTTP, para el caso), no asumiría ciegamente que el resultado siempre sería exitoso 2xx. Y luego, una vez que el desarrollador comience a considerar el manejo de errores, 404 Not Found sería uno de los primeros errores que se le ocurra. En ese momento, con suerte sacaría una conclusión de que, es semánticamente seguro que una operación HTTP DELETE ignore un error 404. Problema resuelto.

RayLuo
fuente