2012-05-23 16 views
18

Imagine un servicio web REST en el que está agregando elementos a algún tipo de contenedor. Por ejemplo, digamos que podríamos añadir un asistente # 789 a un evento # 456 así:¿HTTP 404 es una respuesta adecuada para una operación PUT en la que no se encuentra algún recurso vinculado?

PUT http://..../api/v1/events/456/attendees/789 

Si cualquiera de los casos # 456 o el participante Nº 789 no existen, ¿es correcto para regresar un HTTP 404 (junto con una carga de error detallada explicando cuál era el problema, por ejemplo, { "error" : { "message" : "Event 456 does not exist" , "code" : "404" } }?

Del mismo modo, ¿qué sucede si estoy creando algo nuevo que hace referencia a otro objeto, pero el otro no existe? Por ejemplo, imagine que estoy creando un evento en la ubicación # 123

PUT http://..../api/v1/event 
{ "location": 123, "name": "Party", "date": "2012-05-23", ...etc... } 

Si la ubicación # 123 no existe, ¿también es correcto devolver 404 (junto con los detalles en respuesta)? Si no, ¿qué sería apropiado, solo un 400?

De acuerdo con la especificación HTTP 1.1 http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html

9,6 PUT ... Si el recurso no puede ser creado o modificado con el Request-URI, una respuesta de error apropiado se debe dar que refleja la naturaleza del problema

Así que parece ser una buena votación para responder con 404. sin embargo por alguna razón no puedo poner mi dedo en, respondiendo a PUT (o POST) con un 404 parece extraño para Yo ... Tal vez sea porque 404 significa que no se puede encontrar el recurso, pero en este caso nuestro recurso es en realidad un vínculo entre otros dos recursos, y es uno de esos dos recursos que no se pueden encontrar.

No se preocupe demasiado por mis ejemplos exactos aquí; están hechos para ilustrar el punto. La pregunta principal es: ¿404 es una respuesta adecuada a una operación PUT que falla porque no se encuentra un recurso vinculado?

Sería excelente si puede señalar referencias: me está costando encontrar cualquiera que entre en este nivel de detalle y también sea lo suficientemente creíble. Especialmente en lo que respecta al tratamiento de las relaciones de recursos en el diseño de API REST.

Pensamiento actualizado Estoy pensando que posiblemente el primer ejemplo debería devolver 404, el segundo no debería. El razonamiento es que en el primer caso el recurso que estamos agregando utiliza el evento 456 y el asistente 789 ya que es una clave primaria compuesta; la segunda ubicación del caso es solo una clave externa. En el segundo caso, se debe devolver un error, pero no un 404, posiblemente una Precondición 412 fallida o tal vez solo una Solicitud incorrecta de 400. ¿Pensamientos?

+1

En mi humilde opinión desde el punto de vista del cliente que está comenzando en la raíz ('/') y caminando por la ruta. Si en algún momento no se encuentra alguna parte de la ruta, debe lanzar 404 con entusiasmo. Sería bueno si pudiera proporcionar qué parte realmente falló, pero me parece razonable. –

Respuesta

14

Hay un número de 4xx HTTP status codes. El más probables son 404 o 409:

404 no encontrado

El servidor no ha encontrado nada que coincida con la petición efectiva URI. No se indica si la condición es temporal o permanente. El código de estado 410 (Gone) DEBERÍA ser utilizado si el servidor sabe, a través de algún mecanismo internamente configurable, que un recurso antiguo está permanentemente no disponible y no tiene dirección de reenvío. Este código de estado se usa comúnmente cuando el servidor no desea que revele exactamente por qué se rechazó la solicitud o cuando no se aplica ninguna otra respuesta .

409 Conflicto

La solicitud no pudo completarse debido a un conflicto con la corriente estado del recurso. Este código solo está permitido en situaciones en las que se espera que el usuario pueda resolver el conflicto y vuelva a enviar la solicitud. El cuerpo de respuesta DEBE incluir suficiente información para que el usuario reconozca el origen del conflicto. Idealmente, la representación 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 requerido.

Es probable que se produzcan conflictos en respuesta a una solicitud PUT. Para el ejemplo , si las versiones se estaban utilizando y la representación es 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 puede ' Completa la solicitud. En este caso , la representación de respuesta probablemente contendría una lista de las diferencias entre las dos versiones.

Cualquiera de los que sería adecuado, pero creo que me gustaría ir a 409. 404 se utiliza para URI no encontrado pero 409 indica el estado actual del recurso no permite la operación solicitada. En su caso, la solicitud no puede ser satisfecha porque algo anda mal que no lo permite.

+0

409 es una opción posible. La parte sobre "el usuario podría ser capaz de resolver el conflicto y volver a enviar la solicitud" es una arruga interesante. ¿Qué sucede si, para tomar mi ejemplo, las ubicaciones no se pueden agregar a través de la API, o posiblemente no por el usuario debido a su nivel de seguridad? ¿Sigue siendo 409 válido? ¿Es confuso si devolvemos 404 para ese tipo de error y 409 para otros errores casi idénticos en los que el usuario puede usar la API para agregar el elemento faltante? ... Aún así, 409 puede no tener sentido ya que los usuarios probablemente _no pueden_ crear una Ubicación con ID # 123, asumiendo que es una clave asignada automáticamente ... – jlarson

+1

@joelarson: No dice * cómo * el usuario debería resolver el conflicto . Puede ser enviando un correo electrónico que diga "Por favor, agregue la ubicación 123", y los consejos sobre cómo hacerlo podrían incluirse en la respuesta. Yo diría que si la situación es "No se puede hacer X debido a la situación Y", entonces es 409; si es "No puedo localizar URI 'X'", entonces es 404. –

Cuestiones relacionadas