Pregunta Código de respuesta HTTP para POST cuando el recurso ya existe


Estoy construyendo un servidor que permite a los clientes almacenar objetos. Esos objetos están completamente construidos en el lado del cliente, completos con identificadores de objeto que son permanentes durante toda la vida del objeto.

He definido la API para que los clientes puedan crear o modificar objetos usando PUT:

PUT /objects/{id} HTTP/1.1
...

{json representation of the object}

{Id} es la ID del objeto, por lo que es parte de Request-URI.

Ahora, también estoy considerando permitir que los clientes creen el objeto usando POST:

POST /objects/ HTTP/1.1
...

{json representation of the object, including ID}

Como POST se entiende como operación de "agregar", no estoy seguro de qué hacer en caso de que el objeto ya esté allí. ¿Debo tratar la solicitud como solicitud de modificación o debo devolver algún código de error (que)?


554
2017-09-29 21:26


origen


Respuestas:


Mi sentimiento es 409 Conflict es el más apropiado, sin embargo, rara vez se ve en la naturaleza, por supuesto:

La solicitud no pudo completarse debido a un conflicto con el estado actual del recurso. Este código solo se permite en situaciones en las que se espera que el usuario pueda resolver el conflicto y volver a enviar la solicitud. El cuerpo de respuesta DEBERÍA incluir suficiente información para que el usuario reconozca la fuente del conflicto. Idealmente, la entidad de respuesta incluiría suficiente información para que el usuario o el agente de usuario corrijan el problema; sin embargo, eso podría no ser posible y no es obligatorio.

Es más probable que se produzcan conflictos en respuesta a una solicitud PUT. Por ejemplo, si se estaba utilizando el control de versiones y la entidad que está siendo PUT incluye cambios en un recurso que entran en conflicto con los realizados por una solicitud anterior (de terceros), el servidor podría usar la respuesta 409 para indicar que no puede completar la solicitud . En este caso, la entidad de respuesta probablemente contendría una lista de las diferencias entre las dos versiones en un formato definido por la respuesta Content-Type.


677
2017-09-29 21:31



Personalmente voy con la extensión WebDAV 422 Unprocessable Entity.

REST Patterns lo describe como

los 422 Unprocessable Entity El código de estado significa que el servidor entiende el tipo de contenido de la entidad de solicitud (de ahí 415 Unsupported Media Type el código de estado es inapropiado), y la sintaxis de la entidad de solicitud es correcta (por lo tanto, 400 Bad Request el código de estado es inapropiado) pero no pudo procesar las instrucciones contenidas.


57
2017-09-29 21:44



De acuerdo a RFC 7231, un 303 Ver otros Puede ser usado Si el resultado del procesamiento de un POST sería equivalente a un    representación de un recurso existente.


50
2017-11-09 09:54



¿Qué hay de devolver un 418?

Debido a que el cliente solicita persistir una entidad que ya existe en el servidor, el servidor finalmente se enoja y piensa que es una tetera y regresa: 418 I'm a teapot.

Referencias


15
2017-07-20 20:39



Tarde en el juego tal vez, pero me encontré con este problema de semántica al intentar crear una API REST.

Para ampliar un poco la respuesta de Wrikken, creo que podrías usar cualquiera 409 Conflict o 403 Forbidden dependiendo de la situación; en resumen, use un error 403 cuando el usuario no puede hacer absolutamente nada para resolver el conflicto y completar la solicitud (por ejemplo, no puede enviar un mensaje de error). DELETEsolicite eliminar explícitamente el recurso), o use 409 si se pudiera hacer algo.

10.4.4 403 prohibido

El servidor entendió la solicitud, pero se niega a cumplirla.   La autorización no ayudará y la solicitud NO DEBE repetirse. Si   el método de solicitud no era HEAD y el servidor desea hacer público   por qué la solicitud no se ha cumplido, DEBERÍA describir el motivo   por el rechazo en la entidad. Si el servidor no desea hacer   esta información disponible para el cliente, el código de estado 404 (No   Encontrado) se puede utilizar en su lugar.

Hoy en día, alguien dice "403" y me viene a la mente un permiso o problema de autenticación, pero la especificación dice que básicamente es el servidor que le dice al cliente que no va a hacerlo, no lo vuelva a preguntar, y esta es la razón por la cual el cliente no debería 't.

Como para PUT vs. POST... POST debería usarse para crear una nueva instancia de un recurso cuando el usuario no tiene medios para crear un identificador para el recurso o no debería hacerlo. PUT se usa cuando se conoce la identidad del recurso.

9.6 PUT

...

La diferencia fundamental entre las solicitudes POST y PUT es   reflejado en el diferente significado del URI de Solicitud. El URI en una   La solicitud POST identifica el recurso que manejará el adjunto   entidad. Ese recurso podría ser un proceso de aceptación de datos, una puerta de entrada a   algún otro protocolo, o una entidad separada que acepta anotaciones. En   Por el contrario, el URI en una solicitud PUT identifica la entidad adjunta con   la solicitud: el agente de usuario sabe qué URI está destinado y el   el servidor NO DEBE intentar aplicar la solicitud a algún otro recurso.   Si el servidor desea que la solicitud se aplique a un URI diferente,

DEBE enviar una respuesta 301 (Movido permanentemente); el agente de usuario MAYO   luego tome su propia decisión con respecto a si redirigir o no   solicitud.


14
2017-12-24 22:40



"302 Encontrado" suena lógico para mí. Y el RFC 2616 dice que PUEDE ser respondida para otras solicitudes además de GET y HEAD (y esto seguramente incluye POST)

Pero todavía mantiene al visitante yendo a esta URL para obtener este recurso "Encontrado", por el RFC. Para que vaya directamente a la URL real "Encontrado" uno debe usar "303 Ver Otro", lo cual tiene sentido, pero fuerza a otra llamada a OBTENER su siguiente URL. En el lado bueno, este GET es almacenable en caché.

Creo que Yo usaría "303 See Other". No sé si puedo responder con la "cosa" encontrada en el cuerpo, pero me gustaría hacerlo para guardar una ida y vuelta al servidor.

ACTUALIZAR: Después de volver a leer el RFC, todavía creo que un inexistente El código "4XX + 303 Encontrado" debería ser el correcto. sin embargo, el "409 Conflict" es el mejor código de respuesta existente (como señaló @ Wrikken), tal vez incluyendo un encabezado de ubicación que apunta al recurso existente.


12
2018-05-16 09:25



No creo que debas hacer esto.

El POST es, como saben, para modificar la colección y se usa para CREAR un nuevo elemento. Entonces, si envía la identificación (creo que no es una buena idea), debe modificar la colección, es decir, modificar el elemento, pero es confuso.

Úselo para agregar un artículo, sin identificación. Es la mejor práctica.

Si desea capturar una restricción ÚNICA (no la identificación) puede responder 409, como puede hacer en las solicitudes PUT. Pero no la ID.


9
2017-09-30 10:12



Creo que para REST, solo tienes que tomar una decisión sobre el comportamiento de ese sistema en particular, en cuyo caso, creo que la respuesta "correcta" sería una de las respuestas dadas aquí. Si desea que la solicitud pare y se comporte como si el cliente hubiera cometido un error que necesita corregir antes de continuar, utilice 409. Si el conflicto realmente no es tan importante y desea mantener la solicitud en marcha, responda redirigiendo el cliente a la entidad que se encontró. Creo que las API REST apropiadas deberían redireccionar (o al menos proporcionar el encabezado de ubicación) al punto final GET para ese recurso después de un POST de todos modos, por lo que este comportamiento proporcionaría una experiencia consistente.

EDITAR: También vale la pena señalar que debes considerar un PUT ya que estás proporcionando la identificación. Entonces el comportamiento es simple: "No me importa lo que hay ahora, pon esto ahí". Es decir, si no hay nada allí, se creará; si hay algo allí, será reemplazado. Creo que un POST es más apropiado cuando el servidor maneja esa ID. Separar los dos conceptos básicamente le dice cómo manejarlo (es decir, PUT es idempotente, por lo que siempre debe funcionar siempre que la carga útil valide, POST siempre crea, de modo que si hay una colisión de ID, entonces un 409 describiría ese conflicto) .


6
2017-10-27 04:51



Por qué no un 202 Aceptado? Es una solicitud OK (200s), no hubo errores del cliente (400s), per se.

De 10 definiciones de código de estado:

"202 Aceptado. La solicitud se ha aceptado para su procesamiento, pero el procesamiento no se ha completado".

... porque no era necesario que se completara, porque ya existía. El cliente no sabe que ya existía, no hicieron nada malo.

Me inclino por lanzar un 202 y devolver contenido similar a lo que GET /{resource}/{id} habría vuelto.


5
2018-03-17 22:12



Otro tratamiento potencial es usar PATCH después de todo. Un PATCH se define como algo que cambia el estado interno y no está restringido a agregarse.

PATCH resolvería el problema al permitirle actualizar elementos ya existentes. Ver: RFC 5789: PARCHE


4
2017-09-07 11:33