Estoy trabajando en un proyecto y después de discutir con la gente en el trabajo durante más de una hora. Decidí saber qué diría la gente en el intercambio de fichas.
Estamos escribiendo una API para un sistema, hay una consulta que debería devolver un árbol de Organización o un árbol de Objetivos.
El árbol de Organización es la organización en la que el usuario está presente. En otras palabras, este árbol siempre debe existir. En la organización, un árbol de meta debe estar siempre presente. (ahí es donde comenzó la discusión). En caso de que el árbol no exista, mi compañero de trabajo decidió que sería correcto responder la respuesta con el código de estado 200. Y luego comenzó a pedirme que arregle mi código porque la aplicación se estaba desmoronando cuando no hay árbol.
Intentaré evitar las llamas y la furia.
Sugerí generar un error 404 cuando no hay árbol. Al menos me dejaría saber que algo está mal. Cuando uso 200, tengo que agregar una verificación especial a mi respuesta en la devolución de llamada exitosa para manejar errores. Espero recibir un objeto, pero en realidad puedo recibir una respuesta vacía porque no se encuentra nada. Suena totalmente justo marcar la respuesta como un 404. Y luego comenzó la guerra y recibí el mensaje de que no entendía el esquema del código de estado HTTP. ¿Entonces estoy aquí y pregunto qué le pasa al 404 en este caso? Incluso recibí el argumento "No encontró nada, así que es correcto devolver 200". Creo que está mal ya que el árbol debe estar siempre presente. Si no encontramos nada y esperamos algo, debería ser un 404.
Más información,
Olvidé agregar las URL que se obtienen.
Organizaciones
/OrgTree/Get
Metas
/GoalTree/GetByDate?versionDate=...
/GoalTree/GetById?versionId=...
Mi error, se requieren ambos parámetros. Si se proporciona cualquier versiónDate que se pueda analizar a una fecha, devolverá la revisión de cierre. Si ingresa algo en el pasado, devolverá la primera revisión. Si por Id con un id que no existe, sospecho que devolverá una respuesta vacía con 200.
Extra
Además, creo que la mejor respuesta al problema es crear objetos predeterminados cuando se crean organizaciones, no tener un árbol no debería ser un caso válido y debería verse como un comportamiento indefinido. No hay forma de que se pueda usar una cuenta sin ambos árboles. Por eso, deben estar siempre presentes.
También me vinculó esto (uno similar pero no puedo encontrarlo)
http://viswaug.files.wordpress.com/2008/11/http-headers-status1.png
fuente
/GoalTree/GetById?versionId=CompletelyInvalidID
volver? No fue un éxito, ya que el recurso nombrado/GoalTree/GetById?versionId=CompletelyInvalidID
literalmente no se encontró.Respuestas:
En caso de duda, consulte la documentación . Al revisar las definiciones del W3C para los códigos de estado HTTP, nos da esto:
En el contexto de su API, depende mucho de cómo se crean las consultas y cómo se recuperan los objetos. Pero, mi interpretación siempre ha sido que:
200
código de retorno , si no existe, devuelve el404
código correcto .200
código. La razón de esto es que la consulta fue válida, tuvo éxito y la consulta no devolvió nada.Entonces, en este caso está en lo correcto , el servicio no está buscando "una cosa específica", está solicitando una cosa en particular, si esa cosa no se encuentra, dígalo claramente.
Creo que Wikipedia lo pone mejor:
Me parece bastante claro.
En cuanto a las solicitudes de ejemplo
Para el formato, usted dijo, siempre devuelve la revisión más cercana a esa fecha. Nunca devolverá un objeto, por lo que siempre debería estar regresando
200 OK
. Incluso si esto fuera capaz de tomar un rango de fechas, y la lógica fuera devolver todos los objetos dentro de ese marco de tiempo devolviendo 200 OK - 0 Los resultados están bien, ya que para eso estaba la solicitud - el conjunto de cosas que cumplían con ese criterio.Sin embargo, este último es diferente ya que solicita un objeto específico , presumiblemente único, con esa identidad. Volver
200 OK
en este caso es incorrecto ya que el recurso solicitado no existe y no se encuentra .En cuanto a elegir códigos de estado
Usted mencionó en un comentario usando un código 5xx, pero su sistema está funcionando. Se le hizo una consulta que no funciona y que necesita comunicarla a la UA. No importa cómo lo cortes, este es territorio 4xx.
Considere un extraterrestre que consulta nuestro sistema solar
fuente
Ignorando el hecho de que / GoalTree / Get * parece un verbo, no recursos, siempre debe devolver 200 porque el URI / GoalTree / Get * representa recursos que siempre están disponibles para el acceso y no es un error del cliente si no hay un árbol como resultado de una solicitud. Simplemente devuelva 200 con un conjunto vacío cuando no haya una entidad que se devolverá.
Utiliza 404 si no se encuentra el recurso, no cuando no hay entidad.
Dicho de otra manera, si desea devolver 404 para sus objetos, entonces dele sus propios URI.
fuente
/GoalTree/GetById?versionId=12345
es un URI perfectamente bueno (bueno, uno relativo, al menos) que identifica un recurso específico, es decir, los datos correspondientes a la ID de versión12345
en el sistema. Si no existen datos con tal ID, una respuesta HTTP 404 es perfectamente apropiada. Por supuesto, el cuerpo de la respuesta debe, en cualquier caso, contener una respuesta con el formato adecuado (por ejemplo, JSON, si eso es lo que esperan los clientes que solicitan tales recursos) que indique la naturaleza específica y la causa del error.Esta es una pregunta interesante, porque se trata de la especificación del sistema.
La respuesta de imel96 me ha convencido de que un 404 no sería una respuesta adecuada, ya que la familia de códigos 4xx es principalmente para errores de usuario / cliente , y este no es uno. La URL está bien formada y el árbol debe estar allí; si no es así, ¡el sistema está en un estado inconsistente!
Por lo tanto, este es un error del servidor , es decir, algo en la familia 5xx. Posiblemente un error genérico del servidor interno 500 o un servicio 503 no disponible (el servicio es "traerme el árbol que debe estar allí").
fuente
Yo diría que un código de respuesta 200 o 404 puede ser válido , dependiendo de cómo se mire la situación.
La cuestión es que los códigos de respuesta HTTP se definen en el contexto de un servidor , que puede entregar varios recursos en función de su URL. En este contexto, los significados de
200 OK
y404 Not Found
son perfectamente inequívocos: el primero dice "aquí está el recurso que solicitó", mientras que el segundo dice "lo siento, no tengo ningún recurso como ese".Sin embargo, en su situación, tiene una capa de aplicación adicional entre el servidor HTTP y los recursos reales (árboles) que se solicitan. La aplicación ocupa una especie de espacio intermedio que no está bien tratado en la especificación HTTP.
Desde el punto de vista del servidor web, las miradas de aplicación tipo de como un recurso: es típicamente un archivo en el servidor, identificado por (una parte de) la URL, al igual que otros recursos (por ejemplo, archivos estáticos) el servidor puede servir. Por otro lado, es un tipo de recurso extraño, ya que consiste en un código ejecutable que determina dinámicamente el contenido y, de hecho, incluso el código de estado de la respuesta, lo que hace que se comporte de alguna manera más como un mini servidor.
En particular, en su caso de ejemplo, el servidor web puede localizar la aplicación muy bien, pero la aplicación no puede localizar el subrecurso (árbol) que se ha solicitado. Ahora, si considera que la aplicación es solo una extensión del servidor y el subpunto (árbol) es el recurso real, entonces es apropiada una respuesta 404 : el servidor simplemente ha delegado la tarea de encontrar el recurso real en la aplicación , que a su vez no ha podido hacerlo.
Por otro lado, si su punto de vista es que la aplicación es el recurso que se solicita, entonces obviamente el servidor web debería devolver una respuesta 200 ; después de todo, la aplicación fue encontrada y ejecutada correctamente. Obviamente, en este caso, la aplicación debería devolver un cuerpo de respuesta válido en el formato esperado, indicando (usando cualquier protocolo de nivel superior que codifique el formato) que no se encontraron datos reales que coincidan con la consulta.
Ambos puntos de vista pueden tener sentido. En la mayoría de los casos , al menos para las aplicaciones destinadas a acceder directamente a través de HTTP con un navegador web común, preferiría la vista anterior : al usuario generalmente no le importan los detalles internos como la diferencia entre el servidor y la aplicación, simplemente preocuparse por si los datos que querían están allí o no.
Sin embargo, en el caso específico de una aplicación diseñada para comunicarse con otros programas de computadora usando un protocolo API de alto nivel personalizado, usando HTTP solo como una capa de transporte de bajo nivel , hay un argumento a favor de esta última vista : para clientes que interactúan con una aplicación de este tipo, todo lo que realmente les importa, a nivel HTTP , es si lograron contactar con éxito la aplicación o no. Todo lo demás, en tales casos, a menudo se comunica de forma más natural utilizando el protocolo de nivel superior.
En cualquier caso, independientemente de cuál de las vistas anteriores prefiera, hay algunos detalles que debe tener en cuenta. Una es que, en muchos casos, puede haber una distinción significativa entre un recurso (esencialmente) vacío y uno inexistente .
En el nivel HTTP, un recurso vacío simplemente se indicaría con un código de respuesta 200 y un cuerpo de respuesta vacío, mientras que un recurso inexistente se indicaría con una respuesta 404 y un cuerpo de recurso explicando la ausencia del recurso. En un protocolo API de nivel superior, uno normalmente indicaría un recurso inexistente mediante una respuesta de error, que contiene un código / mensaje de error específico de protocolo adecuado, mientras que una respuesta vacía simplemente sería una estructura de respuesta normal sin elementos de datos.
(Tenga en cuenta que un recurso no necesita tener literalmente cero bytes de longitud para estar "vacío" en el sentido que quiero decir más arriba. Por ejemplo, un resultado de búsqueda sin elementos coincidentes contaría como vacío en sentido amplio, como lo haría un resultado de consulta SQL con sin filas o un documento XML que no contenga datos reales).
También, por supuesto, si la aplicación realmente cree que el subrecurso solicitada debería estar allí, pero no lo encuentra, entonces existe un tercer código de respuesta posible:
500 Internal Server Error
. Tal respuesta tiene sentido si la existencia del recurso es una condición previa asumida para la aplicación, de modo que su ausencia indica necesariamente un mal funcionamiento interno.Finalmente, siempre debes tener en cuenta la ley de Postel :
Si el servidor debe responder en una situación particular con un 200 o un 404 respuesta, eso no es excusa que como el cliente implementador de la manipulación, ya sea la respuesta apropiada y de la manera que maximiza la interoperabilidad robusta. Por supuesto, se puede argumentar qué significa el manejo "apropiado" en diferentes situaciones, pero ciertamente no debería incluir normalmente la caída o "desmoronamiento".
fuente
¿Qué tal un 204 Sin contenido? Sugeriría que su solicitud se procesó correctamente pero no devuelve nada. Todavía es un "éxito", pero le permite ver si tiene resultados basados únicamente en el código de estado.
fuente
Si la URL representa un recurso que nunca existió, devuelva 404 No encontrado
Si la URL representa un recurso que es una lista vacía, devuelva una lista vacía y 200 OK.
Ejemplo:
Si la URL representa un recurso que solía existir, devuelve 410 Gone.
Con respecto al diálogo de Lego Stormtrooper:
fuente
Por lo que parece, esta es una API para uso interno . Esto ofrece la ventaja de utilizar el esquema que ofrezca el mayor beneficio , independientemente de si se trata de un libro (especificación) o no. Esto no significa inventar completamente sus propios códigos de estado, pero está bien 'doblar' un poco las reglas si es beneficioso.
Estoy de acuerdo con su soporte en que debe obtener un código de estado que muestre que algo salió mal. Esto es, después de todo, para qué sirven los códigos de estado. También obtienes el beneficio de bibliotecas que lanzan excepciones / etc. en código de estado no 200 para que no tenga que verificar explícitamente (o puede escribir su propio contenedor que haga esto).
También estoy de acuerdo con el punto de vista de Andrés F. de que 500 es apropiado ya que el árbol debería existir. Sin embargo, en la práctica, me gusta dividir los errores del servidor en dos categorías. Algo inesperado salió mal y algo que prácticamente puedo verificar salió mal. Esto da como resultado los siguientes códigos de estado,
En su caso particular, puede verificar si el árbol existe o no en el lado del servidor y, si no está allí, devolver un 409. Es un error esperado (sabe que puede suceder, puede verificarlo, etc.) . El conflicto 409 es solo mi preferencia personal, un 5xx también puede ser apropiado siempre que pueda sentarse y decidir esto con su equipo.
La categorización de códigos como este lo ayuda a identificar más rápidamente el tipo de error, pero puede tener beneficios más allá de la organización. A menudo, con los errores del sitio web, no desea que el cliente reciba errores inesperados, ya que esto puede ser un problema de seguridad y revelar vulnerabilidades, por lo que devuelve un 500 genérico "Se produjo un error". y registre el error completo en el servidor. Pero si se produce un error esperado como 409, sabe que sería seguro mostrar el error al cliente y no tiene que dejarlo en la oscuridad en cuanto a lo que sucedió. Este es solo un uso práctico que puedo contar, pero hay muchas posibilidades.
Esto es un poco complicado porque estás publicando esto porque no puedes estar de acuerdo con tus compañeros de trabajo, pero parece que ustedes están discutiendo más sobre la semántica y quién es políticamente correcto. Realmente no importa quién sea más adecuado, siempre y cuando pueda idear un sistema que beneficie más a la empresa.
Por otro lado, si esta es una API pública, seguir las especificaciones lo más cerca posible sería más importante para evitar confusiones entre la comunidad.
fuente
Tomando una puñalada tangencial a esto: si un humano finalmente está utilizando la API (a través de una GUI), sugeriría hacer lo que sea que haga la vida más fácil para el usuario final. La inexistencia del árbol cuando debería existir es un error de "inconsistencia del modelo de dominio". Un error del sistema es cuando se quedó sin memoria o tuvo alguna otra falla sistémica. Entonces devolver 5xx es inapropiado. Como mencionan varias personas anteriormente, 4xx podría ser apropiado si el árbol en sí tuviera su propio URI, que no es el caso aquí. Pero esto es lo que 404 le dice al cliente: puede intentarlo una y otra vez hasta que recupere algo. Si devolvió 200, podría devolver suficientes diagnósticos al usuario o agente de usuario para que el agente de usuario pueda mostrar una medición para que el usuario deje de volver a intentarlo y solo contacte al soporte. Por otro lado, si esta API está destinada solo a sistemas,
fuente