Estoy creando una API REST, pero he encontrado un problema.
Parece que la práctica aceptada en el diseño de una API REST es que si el recurso solicitado no existe, se devuelve un 404.
Sin embargo, para mí, esto agrega ambigüedad innecesaria. HTTP 404 se asocia más tradicionalmente con un URI incorrecto. Entonces, en efecto, estamos diciendo "¡O llegaste al lugar correcto, pero ese registro específico no existe, o no existe tal ubicación en Internet! Realmente no estoy seguro de cuál ..."
Considere el siguiente URI:
http://mywebsite/api/user/13
Si recibo un 404, ¿es porque el Usuario 13 no existe? ¿O es porque mi URL debería haber sido:
http://mywebsite/restapi/user/13
En el pasado, acabo de devolver un resultado NULL con un HTTP 200 OK
código de respuesta si el registro no existe. Es simple y, en mi opinión, muy limpio, incluso si no es necesariamente una práctica aceptada. ¿Pero hay una mejor manera de hacer esto?
fuente
Respuestas:
404 es solo el código de respuesta HTTP. Además de eso, puede proporcionar un cuerpo de respuesta y / u otros encabezados con un mensaje de error más significativo que los desarrolladores verán.
fuente
Úselo
404
si el recurso no existe. No vuelvas200
con el cuerpo vacío.Esto es similar a
undefined
vs cadena vacía (por ejemplo""
) en programación. Si bien es muy similar, definitivamente hay una diferencia.404
significa que no existe nada en ese URI (como una variable indefinida en la programación). Volver200
con un cuerpo vacío significa que algo existe allí y que algo está vacío en este momento (como una cadena vacía en la programación).404
no significa que fue un "URI malo". Hay códigos HTTP especiales que están destinados a errores de URI (por ejemplo414 Request-URI Too Long
).fuente
String getName()
que tiene una aplicación como esta:return this.name == null ? "" : this.name
. Eso no es incorrecta a menos que desee el cliente sepa quethis.name
esnull
.Como con la mayoría de las cosas, "depende". Pero para mí, su práctica no es mala y no va en contra de la especificación HTTP per se . Sin embargo, aclaremos algunas cosas.
Primero, los URI deben ser opacos. Incluso si no son opacos para las personas, son opacos para las máquinas. En otras palabras, la diferencia entre
http://mywebsite/api/user/13
,http://mywebsite/restapi/user/13
es la misma que la diferencia entrehttp://mywebsite/api/user/13
y,http://mywebsite/api/user/14
es decir, no es la misma, no es el mismo período. Entonces, un 404 sería completamente apropiado parahttp://mywebsite/api/user/14
(si no hay tal usuario) pero no necesariamente la única respuesta apropiada.También puede devolver una respuesta 200 vacía o más explícitamente una respuesta 204 (Sin contenido). Esto transmitiría algo más al cliente. Implicaría que el recurso identificado por
http://mywebsite/api/user/14
no tiene contenido o es esencialmente nada. Lo que significa que no es un recurso de este tipo. Sin embargo, no necesariamente significa que usted está afirmando que persiste algún usuario en un almacén de datos con ID 14. Esa es su preocupación privada, no la preocupación del cliente que hace la solicitud. Entonces, si tiene sentido modelar sus recursos de esa manera, adelante.Existen algunas implicaciones de seguridad al proporcionar información a sus clientes que les facilitaría adivinar los URI legítimos. Devolver un 200 por fallas en lugar de un 404 puede darle al cliente una pista de que al menos la
http://mywebsite/api/user
parte es correcta. Un cliente malintencionado podría seguir intentando diferentes enteros. Pero para mí, un cliente malintencionado podría adivinar lahttp://mywebsite/api/user
parte de todos modos. Un mejor remedio sería usar UUID.http://mywebsite/api/user/3dd5b770-79ea-11e1-b0c4-0800200c9a66
es decir, es mejor quehttp://mywebsite/api/user/14
. Al hacer eso, podría usar su técnica de devolver 200 sin revelar mucho.fuente
404 No encontrado técnicamente significa que actualmente URI no se map a un recurso. En su ejemplo, interpreto una solicitud
http://mywebsite/api/user/13
que devuelve un 404 para implicar que esta url nunca se asignó a un recurso. Para el cliente, ese debería ser el final de la conversación.Para abordar las inquietudes con ambigüedad, puede mejorar su API proporcionando otros códigos de respuesta. Por ejemplo, suponga que desea permitir a los clientes emitir solicitudes GET a la url
http://mywebsite/api/user/13
, desea comunicar que los clientes deben usar la url canónicahttp://mywebsite/restapi/user/13
. En ese caso, es posible que desee considerar la posibilidad de emitir una redirección permanente al devolver un 301 Moved Permanently y proporcionar la URL canónica en el encabezado Ubicación de la respuesta. Esto le dice al cliente que para futuras solicitudes deben usar la URL canónica.fuente
Entonces, en esencia, parece que la respuesta podría depender de cómo se forma la solicitud.
Si el recurso solicitado forma parte del URI según una solicitud
http://mywebsite/restapi/user/13
y el usuario 13 no existe, entonces un 404 es probablemente apropiado e intuitivo porque el URI es representativo de un usuario / entidad / documento / etc inexistente. Lo mismo se aplicaría a la técnica más segura utilizando un GUIDhttp://mywebsite/api/user/3dd5b770-79ea-11e1-b0c4-0800200c9a66
y el argumento api / restapi anterior.Sin embargo, si el ID del recurso solicitado se incluyó en el encabezado de la solicitud [incluya su propio ejemplo] o, de hecho, en el URI como parámetro, por ejemplo
http://mywebsite/restapi/user/?UID=13
, el URI seguiría siendo correcto (porque el concepto de USUARIO existe enhttp://mywebsite/restapi/user/
); y por lo tanto, se podría esperar razonablemente que la respuesta sea 200 (con un mensaje detallado apropiado) porque el usuario específico conocido como 13 no existe pero el URI sí. De esta manera, decimos que el URI es bueno, pero la solicitud de datos no tiene contenido.Personalmente, un 200 todavía no se siente bien (aunque ya he argumentado que sí). Un código de respuesta 200 (sin una respuesta detallada) podría causar que no se investigue un problema cuando se envía una identificación incorrecta, por ejemplo.
Un mejor enfoque sería enviar una
204 - No Content
respuesta. Esto cumple con la descripción de w3c * El servidor ha cumplido la solicitud pero no necesita devolver un cuerpo de entidad, y podría querer devolver metainformación actualizada. * 1 La confusión, en mi opinión, es causada por la entrada de Wikipedia que indica 204 Sin contenido - El servidor procesó con éxito la solicitud, pero no devuelve ningún contenido. Usualmente se usa como respuesta a una solicitud de eliminación exitosa .La última oración es muy discutible. Considere la situación sin esa oración y la solución es fácil: solo envíe un 204 si la entidad no existe. Incluso hay un argumento para devolver un 204 en lugar de un 404, ¡la solicitud se ha procesado y no se ha devuelto ningún contenido! Sin embargo, tenga en cuenta que los 204 no permiten contenido en el cuerpo de respuestaFuentes
http://en.wikipedia.org/wiki/List_of_HTTP_status_codes 1. http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
fuente
Esa es una publicación muy antigua pero me enfrenté a un problema similar y me gustaría compartir mi experiencia con ustedes.
Estoy construyendo una arquitectura de microservicios con API de descanso. Tengo algunos servicios GET de descanso, recopilan datos del sistema de fondo en función de los parámetros de solicitud.
Seguí el resto de los documentos de diseño de la API y envié HTTP 404 con un mensaje de error JSON perfecto al cliente cuando no había datos que se alinearan con las condiciones de la consulta (por ejemplo, se seleccionó el registro cero).
Cuando no había datos para enviar de vuelta al cliente, preparé un mensaje JSON perfecto con código de error interno, etc. para informar al cliente sobre el motivo de "No encontrado" y se lo devolvió al cliente con HTTP 404. Eso funciona bien.
Más tarde, he creado una clase de cliente API de descanso que es un ayudante fácil para ocultar el código relacionado con la comunicación HTTP y usé este ayudante todo el tiempo cuando llamé a mis API de descanso desde mi código.
PERO necesitaba escribir código extra confuso solo porque HTTP 404 tenía dos funciones diferentes:
Importante: mi controlador de errores de la API de rest detecta todas las excepciones que aparecen en el servicio de back-end, lo que significa que, en caso de error, mi API de rest siempre regresa con un mensaje JSON perfecto con los detalles del mensaje.
Esta es la primera versión del método auxiliar de mi cliente que maneja las dos respuestas HTTP 404 diferentes:
PERO , debido a que mi cliente Java o JavaScript puede recibir dos tipos de HTTP 404 de alguna manera, necesito verificar el cuerpo de la respuesta en el caso de HTTP 404. Si puedo analizar el cuerpo de la respuesta, entonces estoy seguro de que recibí una respuesta donde había No hay datos para enviar al cliente.
Si no puedo analizar la respuesta, eso significa que recuperé un HTTP 404 real del servidor web (no de la aplicación API del resto).
Es muy confuso y la aplicación cliente siempre necesita realizar un análisis adicional para verificar la razón real de HTTP 404.
Sinceramente, no me gusta esta solución. Es confuso, necesita agregar código extra de mierda a los clientes todo el tiempo.
Entonces, en lugar de usar HTTP 404 en estos dos escenarios diferentes, decidí que haré lo siguiente:
En ese caso, el código del cliente puede ser más elegante:
Creo que esto maneja ese problema mejor.
Si tiene alguna solución mejor, compártala con nosotros.
fuente
Este viejo pero excelente artículo ... http://www.infoq.com/articles/webber-rest-workflow dice esto al respecto ...
404 Not Found: el servicio es demasiado vago (o seguro) para darnos una razón real por la cual nuestra solicitud falló, pero sea cual sea la razón, tenemos que lidiar con ella.
fuente
El identificador uniforme de recursos es un puntero único al recurso. Un URI de forma pobre no apunta al recurso y, por lo tanto, realizar un GET en él no devolverá un recurso. 404 significa que el servidor no ha encontrado nada que coincida con el URI de solicitud. Si ingresó el URI incorrecto o URI incorrecto, ese es su problema y la razón por la que no llegó a un recurso, ya sea una página HTML o IMG.
fuente
Para este escenario, HTTP 404 es el código de respuesta para la respuesta de la API REST Al igual que 400, 401, 404, 422 entidad no procesable
use el manejo de excepciones para verificar el mensaje de excepción completo.
Este bloque de excepción le da el mensaje correcto lanzado por la API REST
fuente