Si una operación RESTful 'PUT' devuelve algo


437

Me preguntaba cuáles son las opiniones de las personas sobre una PUToperación RESTful que no devuelve nada (nulo) en el cuerpo de respuesta.

Respuestas:


615

La especificación HTTP ( RFC 2616 ) tiene una serie de recomendaciones que son aplicables. Aquí está mi interpretación:

  • Código de estado HTTP 200 OKpara una PUT exitosa de una actualización de un recurso existente. No se necesita cuerpo de respuesta. (Según la Sección 9.6 , 204 No Contentes aún más apropiado).
  • El código de estado HTTP 201 Createdpara un PUT exitoso de un nuevo recurso, con el URI más específico para el nuevo recurso devuelto en el campo del encabezado Ubicación y cualquier otro URI y metadato relevante del recurso se hizo eco en el cuerpo de respuesta. ( RFC 2616 Sección 10.2.2 )
  • Código de estado HTTP 409 Conflictpara un PUT que es correcto debido a un 3 rd modificación -party, con una lista de diferencias entre el intento de actualización y el recurso actual en el cuerpo de la respuesta. ( RFC 2616 Sección 10.4.10 )
  • Código de estado HTTP 400 Bad Requestpara un PUT fallido, con texto en lenguaje natural (como el inglés) en el cuerpo de la respuesta que explica por qué falló el PUT. ( RFC 2616 Sección 10.4 )

25
@stian ¡Interesante! Eso parece bastante presuntuoso por parte de Mozilla, ya que no puedo encontrar nada en RFC 2616 (en particular, las secciones 10.2 Exitosas 2xx y 10.2.1 200 OK ) que excluyen específicamente el uso de 200para PUT, DELETE o cualquier otro método. ¿Me he perdido algo? ¿Como que Mozilla se convierta en el jefe de W3 y el IETF? ;) O tal vez nunca hayan oído hablar del Principio de Robustez de Postel.
PAUSE del sistema el

52
@stian: Esa frase fue eliminada el 3 de febrero de 2013. Probablemente porque alguien leyó sobre esto aquí. ;) developer.mozilla.org/en-US/docs/HTTP/…
Christian Strempfer

66
La semántica del método PUT es ignorar cualquier estado actual en el que se encuentre el recurso, por lo tanto, devolver un conflicto 409 para un PUT que no tiene éxito debido a una modificación de terceros solo tiene sentido si la solicitud es condicional.
Pedro Werneck

8
@systemPAUSE Buena respuesta. Un pequeño punto: si no va a devolver un cuerpo de respuesta a una operación exitosa, sugeriría usar un 204 exclusivamente. Algunos clientes (jQuery Ajax, por ejemplo) se ahogarán si esperan una respuesta de longitud distinta de cero pero no la obtienen. Puedes ver un ejemplo de esto en esta pregunta .
nick_w

3
Posiblemente RFC2616 ha sido actualizado desde que esto fue respondido. En ningún lugar en 9.6 se menciona No response body neededen relación con un 200. De hecho, el cuerpo de respuesta no se menciona en absoluto en relación con un PUT. Solo diceIf an existing resource is modified, either the 200 (OK) or 204 (No Content) response codes SHOULD be sent to indicate successful completion of the request.
James

164

A diferencia de la mayoría de las respuestas aquí, en realidad creo que PUT debería devolver el recurso actualizado (además del código HTTP, por supuesto).

La razón por la que desea devolver el recurso como respuesta para la operación PUT es porque cuando envía una representación de recursos al servidor, el servidor también puede aplicar algún procesamiento a este recurso, por lo que al cliente le gustaría saber cómo funciona este recurso parece que después de que la solicitud se completó con éxito. (de lo contrario, tendrá que emitir otra solicitud GET).


3
"el servidor también puede aplicar algo de procesamiento a este recurso": Soy nuevo en esto. ¿Es eso realmente RESTANTE?
Raedwald

22
@Raedwald seguro que lo es. REST no requiere que todo el recurso se actualice en un PUT, aunque generalmente se recomienda. Es posible que algunos campos no tengan sentido para actualizar: la fecha de creación o la última fecha de modificación, por ejemplo, probablemente no deberían incluirse en el cuerpo de PUT, pero probablemente se cambiarían como resultado de PUT. Dicho esto, no estoy de acuerdo con LiorH en que un PUT debería dar como resultado la devolución del recurso; Necesitaría un GET después del PUT para obtener el recurso actualizado.
Randolpho

19
@Randolpho REST no requiere que se actualice todo el recurso en un PUT, ¿no debería ser este el caso de un PARCHE?
Marco Ciambrone

14
@MarcoCiambrone Sí, estoy de acuerdo y me retracto de mi comentario anterior. He cambiado mi tono en REST y PUT - PUT siempre debe ser idempotente y nunca debe usarse para una actualización parcial. POST es la única alternativa a menos que PATCH sea compatible, en cuyo caso PATCH puede ser una buena alternativa. PATCH es un nuevo verbo, sin embargo, y puede que algunos marcos del lado del servidor no lo admitan.
Randolpho

2
La respuesta se escribió mucho antes de rfc7231, pero la sección 4.3.4 deja en claro "El método PUT solicita que se cree o reemplace el estado del recurso de destino con el estado definido por la representación incluida en la carga útil del mensaje de solicitud"
aaaaaa

3

Creo que es posible que el servidor devuelva contenido en respuesta a un PUT. Si está utilizando un formato envolvente de respuesta que permite datos de carga lateral (como el formato consumido por ember-data), también puede incluir otros objetos que pueden haber sido modificados a través de activadores de bases de datos, etc. (Los datos de carga lateral son explícitamente para reducir # de solicitudes, y este parece ser un buen lugar para optimizar.)

Si solo acepto el PUT y no tengo nada que informar, uso el código de estado 204 sin cuerpo. Si tengo algo que informar, uso el código de estado 200 e incluyo un cuerpo.


2

La especificación HTTP / 1.1 (sección 9.6) analiza los códigos de respuesta / error apropiados. Sin embargo, no aborda el contenido de la respuesta.

¿Qué esperarías? Un simple código de respuesta HTTP (200, etc.) me parece sencillo y sin ambigüedades.


Sí, pero qué pasa si desea verificar si los datos insertados en db después de un PUT o POST realmente representan los datos verdaderos que desea. Sería mejor si el HTTP puede enviar el cuerpo de la respuesta.
tnkh

1
@tnkh lo que sugieres es francamente una idea horrible. Realice una llamada GET por separado después de una actualización exitosa para lograr lo que desea. Para garantizar el rendimiento, introduzca una capa de almacenamiento en caché si tiene problemas en este departamento. No podemos resolver estos problemas jugando con la lógica del tipo "todo funciona". No pierda el tiempo con los principios de programación 'sólidos' y básicos que deberían ser de sentido común en el año 2020. ¡Es una desgracia!
XDS

@XDS Reconozco tu primera parte del comentario. Pero no puedo parar de poner los ojos en blanco después de eso. Comentario hilarante
tnkh

Sin embargo, gracias por detallar por qué te resulta gracioso.
XDS

2

Si el backend de la API REST es una base de datos relacional SQL, entonces

  1. debe tener RowVersion en cada registro que se pueda actualizar (para evitar el problema de actualización perdida )
  2. siempre debe devolver una nueva copia del registro después de PUT (para obtener la nueva RowVersion ).

Si no le importan las actualizaciones perdidas, o si desea obligar a sus clientes a realizar una OBTENCIÓN inmediatamente después de un PUT, no devuelva nada de PUT.


1

Código de respuesta HTTP de 201 para "Creado" junto con un encabezado "Ubicación" para señalar dónde puede encontrar el cliente el recurso recién creado.


55
Los objetos PUT no son (o no deberían ser) recursos recién creados
kdazzle

99
@kdazzle PUT ciertamente puede ser un recurso recién creado, y a menudo lo sería. w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.6
Charlie Schliesser

3
Solo para explicar mi comentario un poco mejor. PUT significa colocar este elemento en esta ubicación específica, reemplazando lo que está actualmente allí (si corresponde).
user1751825

3
Correcto, "reemplazar lo que hay actualmente" es la frase clave. Ya debería existir y está siendo reemplazado. PUT no debe ser para crear nuevos recursos.
Kevin M

3
@KevinM Como en el último documento RFC rfc7231 , dice que se pueden crear recursos: "El método PUT solicita que se cree o reemplace el estado del recurso objetivo [...]" y la razón por la que piensa que PUT no puede crear El nuevo recurso se debe a que no necesariamente conoce la ubicación del nuevo recurso. Pero si conoce su ubicación / identificador, se puede crear si aún no está allí.
Leo Lei

0

Utilicé RESTful API en mis servicios, y aquí está mi opinión: Primero debemos llegar a una vista común: PUTse utiliza para actualizar un recurso que no se crea ni se obtiene.

Definí recursos con: Stateless resourcey Stateful resource:

  • Recursos sin estado Para estos recursos, solo devuelva el HttpCode con el cuerpo vacío, es suficiente.

  • Recursos con estado Por ejemplo: la versión del recurso. Para este tipo de recursos, debe proporcionar la versión cuando desee cambiarla, así que devuelva el recurso completo o devuelva la versión al cliente, de modo que el cliente no necesite enviar una solicitud de obtención después de la acción de actualización.

Pero , para un servicio o sistema, mantenerlosimple,clearly,easy to use and maintaines lo más importante.


66
"PUT se usa para actualizar un recurso que no se crea ni obtiene". Eso no es cierto ni común. Por especificación, PUT puede crear el recurso. Claro = siguiendo la especificación comúnmente conocida.
Imre Pühvel

-3

Del mismo modo que un cuerpo de Solicitud vacío cumple con el propósito original de una solicitud GET y el cuerpo de respuesta vacío cumple con el propósito original de una solicitud PUT.


-3

parece estar bien ... aunque creo que una indicación rudimentaria de éxito / fracaso / tiempo publicado / # bytes recibidos / etc. Sería preferible.

editar: estaba pensando en la línea de integridad de datos y / o mantenimiento de registros; metadatos como un hash MD5 o una marca de tiempo para el tiempo recibido pueden ser útiles para grandes archivos de datos.


1
¿Qué tal 200 OK en el encabezado de respuesta de estado? ¿Crees que eso es suficiente para decir, "funcionó bien, gracias?"
AnthonyWJones

el encabezado de respuesta contendría el código de estado, y sí, estamos hablando de HTTP en este punto :)
AwkwardCoder

-4

Idealmente, devolvería una respuesta de éxito / fracaso.


13
Sin embargo, no en el cuerpo de respuesta. El código de estado HTTP es el lugar para eso. Tal vez si hay un error, podría devolverse alguna información de error extendida en la oferta de respuesta
The Archetypal Paul

-4

Hay una diferencia entre el encabezado y el cuerpo de una respuesta HTTP. PUT nunca debe devolver un cuerpo, sino que debe devolver un código de respuesta en el encabezado. Simplemente elija 200 si tuvo éxito y 4xx si no. No existe un código de retorno nulo. ¿Por qué quieres hacer esto?

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.