REST API error devuelve buenas prácticas [cerrado]

623

Estoy buscando orientación sobre buenas prácticas cuando se trata de devolver errores de una API REST. Estoy trabajando en una nueva API para poder tomar cualquier dirección en este momento. Mi tipo de contenido es XML en este momento, pero planeo admitir JSON en el futuro.

Ahora estoy agregando algunos casos de error, como por ejemplo, un cliente intenta agregar un nuevo recurso pero ha excedido su cuota de almacenamiento. Ya estoy manejando ciertos casos de error con códigos de estado HTTP (401 para autenticación, 403 para autorización y 404 para URI de solicitud incorrecta). Revisé los benditos códigos de error HTTP, pero ninguno del rango 400-417 parece correcto para informar errores específicos de la aplicación. Así que al principio tuve la tentación de devolver el error de mi aplicación con 200 OK y una carga útil XML específica (es decir, ¡Páganos más y obtendrá el almacenamiento que necesita!), Pero me detuve a pensarlo y parece estar enjabonado (/ encogerse de hombros con horror). Además, parece que estoy dividiendo las respuestas de error en casos distintos, ya que algunos están controlados por el código de estado http y otros están controlados por el contenido.

Entonces, ¿cuáles son las recomendaciones de la industria? Buenas prácticas (¡explique por qué!) Y también, desde un punto de vista del cliente, ¿qué tipo de manejo de errores en la API REST facilita la vida del código del cliente?

Remus Rusanu
fuente
77
Solo para aclarar: no estoy tan interesado en qué código de estado HTTP particular devolver, pero si es una buena práctica REST combinar errores de carga útil con códigos de estado HTTP o es mejor confiar únicamente en la carga útil.
Remus Rusanu
3
El Manual de diseño de API REST cubre este tema bastante bien.
Remus Rusanu
12
La pregunta no pide opinión, sino orientación / recomendaciones y debe reabrirse y usarse como referencia. ¿Cuál fue el punto de cerrar en 2016 la pregunta, que se creó en 2009, tiene más de 400 votos y ninguna de las respuestas existentes basadas en opiniones
Michael Freidgeim
44
La mayoría no mencionó, pero el uso de los códigos de error HTTP puede generar problemas con respecto a la causa principal de un problema. HTTP es el protocolo de transporte y un 404 debe indicar que hubo un problema con el URL en el nivel de transporte (por ejemplo, ruta incorrecta). Si la aplicación no puede encontrar un conjunto de datos por su id, se trata de un error de nivel de aplicación (no un error de nivel de transporte) y un 404, según lo sugerido por los usuarios de código de estado http, podría llevar a una conclusión incorrecta. En general, no me gusta la confusión de la capa de transporte y aplicación al usar los códigos de estado.
SCI

Respuestas:

220

Así que al principio tuve la tentación de devolver el error de mi aplicación con 200 OK y una carga útil XML específica (es decir, ¡Páganos más y obtendrá el almacenamiento que necesita!), Pero me detuve a pensarlo y parece estar enjabonado (/ encogerse de hombros con horror).

No devolvería un 200 a menos que realmente no haya nada malo con la solicitud. De RFC2616 , 200 significa "la solicitud ha tenido éxito".

Si se ha excedido la cuota de almacenamiento del cliente (por cualquier razón), devolvería un 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 de la denegación en la entidad. Si el servidor no desea que esta información esté disponible para el cliente, se puede utilizar el código de estado 404 (No encontrado).

Esto le dice al cliente que la solicitud estuvo bien, pero que falló (algo que un 200 no hace). Esto también le brinda la oportunidad de explicar el problema (y su solución) en el cuerpo de respuesta.

¿Qué otras condiciones de error específicas tenía en mente?

Rich Apodaca
fuente
66
¿Debo incluir mi mensaje de error detallado en el cuerpo, es decir. un código XML / par de cadenas? ¿Cómo se las arreglan mejor los clientes con esto? Por ejemplo, sé que los clientes basados ​​en C # WebRequest lanzarían 'Bad Request' o 'Forbidden' y no darían el cuerpo de la respuesta.
Remus Rusanu
18
El cuerpo de un 403 "debería" contiene los detalles del error. Si un cliente está preparado para hacer uso de la información es otra historia. Tiene más sentido que este formato sea el mismo que el formato para todas las demás cargas útiles (por ejemplo, XML, JSON).
Rich Apodaca
1
... y si los detalles no se devuelven en el 403, se puede usar un 404 "puede" en su lugar (sin embargo, no me parece la mejor opción).
Rich Apodaca
66
La opción 404 es para el caso de que un 403 pueda revelar detalles sobre la aplicación que no desea que los usuarios no autorizados conozcan; si un usuario no administrativo golpea una URL solo de administrador, por ejemplo, es posible que no desee ese usuario saber que es una URL válida para administradores, etc. Sin embargo, en este caso, el 403 es completamente apropiado.
Greg Campbell
16
Siento que esta es una respuesta bastante inútil. Pensé que el aspecto más importante es si los estados deberían usarse únicamente, o si la información del error debería devolverse en la carga útil, o ambos, etc. Y luego, cómo la información debería agregarse en la carga útil. El estado específico que se utiliza se centra en un solo aspecto específico de la pregunta.
Manachi
584

Un gran recurso para elegir el código de error HTTP correcto para su API: http://www.codetinkerer.com/2015/12/04/choosing-an-http-status-code.html

Un extracto del artículo:

Donde empezar:

ingrese la descripción de la imagen aquí

2XX / 3XX:

ingrese la descripción de la imagen aquí

4XX:

ingrese la descripción de la imagen aquí

5XX:

ingrese la descripción de la imagen aquí

Omar Ali
fuente
1
422 es específicamente una extensión WebDAV. Creo que eso no debería estar aquí.
Mario
@ Mario Es idiomático en las API de Ruby on Rails devolver 422 en respuesta a las condiciones especificadas aquí. Muchos buenos siguiendo ese enfoque ya. ¿Para qué reemplazaría los usos de 422?
Kelsey Hannan
400 antiguo regular
Andbdrew 05 de
Gracias. ¿Qué significa "¿Estás saliendo furioso de Internet?"
RoutesMaps.com
@ Crimean.us google.com/search?q=define+rage-quit
Omar Ali
87

La opción principal es si desea tratar el código de estado HTTP como parte de su API REST o no.

Ambas formas funcionan bien. Estoy de acuerdo en que, estrictamente hablando, una de las ideas de REST es que debe usar el código de estado HTTP como parte de su API (devuelva 200 o 201 para una operación exitosa y un 4xx o 5xx dependiendo de varios casos de error). , no hay policía REST. Puedes hacer lo que quieras. He visto APIs no REST mucho más atroces que se llaman "RESTful".

En este punto (agosto de 2015), le recomiendo que use el código de estado HTTP como parte de su API. Ahora es mucho más fácil ver el código de retorno al usar frameworks que en el pasado. En particular, ahora es más fácil ver el caso de devolución no 200 y el cuerpo de respuestas no 200 que en el pasado.

El código de estado HTTP es parte de su api

  1. Deberá elegir cuidadosamente los códigos 4xx que se ajusten a sus condiciones de error. Puede incluir un mensaje de reposo, xml o texto sin formato como la carga útil que incluye un subcódigo y un comentario descriptivo.

  2. Los clientes deberán utilizar un marco de software que les permita obtener el código de estado de nivel HTTP. Generalmente factible, no siempre sencillo.

  3. Los clientes tendrán que distinguir entre los códigos de estado HTTP que indican un error de comunicación y sus propios códigos de estado que indican un problema a nivel de aplicación.

El código de estado HTTP NO es parte de su API

  1. El código de estado HTTP siempre será 200 si su aplicación recibió la solicitud y luego respondió (casos de éxito y error)

  2. TODAS sus respuestas deben incluir información de "sobre" o "encabezado". Típicamente algo como:

    sobre_ver: 1.0
    estado: # usa los códigos que quieras. Reserve un código para el éxito.
    msg: "ok" # Una cadena humana que refleja el código. Útil para la depuración.
    data: ... # Los datos de la respuesta, si los hay.
  3. Este método puede ser más fácil para los clientes ya que el estado de la respuesta siempre está en el mismo lugar (no se necesitan subcódigos), no hay límites en los códigos, no es necesario obtener el código de estado de nivel HTTP.

Aquí hay una publicación con una idea similar: http://yuiblog.com/blog/2008/10/15/datatable-260-part-one/

Temas principales:

  1. Asegúrese de incluir números de versión para que luego pueda cambiar la semántica de la API si es necesario.

  2. Documento...

Larry K
fuente
8
Ty Opción 2 parece como jabón en la ropa de descanso, aunque ...
Remus Ruşanu
138
No, hacer un túnel todo a través de un 200 no es nada relajante. Evita que los intermediarios comprendan el resultado de una operación, lo que matará cualquier forma de almacenamiento en caché, oculta la semántica de la operación e impone la comprensión del contenido del mensaje para procesar un error, incumpliendo la restricción de mensajes independientes.
SerialSeb
13
Es posible que devolver los detalles del error con 200 no sea RESTful, pero esta es una respuesta útil (si ignora el comentario "Ambas formas son relajantes") ... El punto más importante puede ser que una API RESTful podría no ser la mejor opción para el OP.
MB.
3
Parece haber una comprensión general de que puede hacer lo que quiera con el protocolo HTTP y aún así ser "RESTy", eso es falso. Use el protocolo para lo que está escrito, esa es una de las ideas centrales de REST. Por lo tanto, el código de estado debe ser parte de su protocolo.
Ariel M.
El objetivo de los códigos de estado es proporcionar un lenguaje común de comprensión entre diversos lenguajes de programación, marcos y enfoques. Los significados del código de estado son casi universales: su cuerpo personalizado, que inherentemente agrega más complejidad a través de la sintaxis personalizada que los consumidores API deben aprender, no lo es.
Kelsey Hannan
40

Recuerde que hay más códigos de estado que los definidos en los RFC HTTP / 1.1, el registro de la IANA se encuentra en http://www.iana.org/assignments/http-status-codes . Para el caso que mencionó, el código de estado 507 suena bien.

Julian Reschke
fuente
3
Hmm, aunque de un vistazo "507 Insufficient Storage" parece que podría ser apropiado, desconfiaría de usarlo ya que está pensado como una extensión WebDAV (bastante específica) y no como un "oye, estás fuera del espacio". excepción. Aún así, supongo que podrías usarlo.
Max
1
No, no es específico de WebDAV en absoluto. Hay una razón por la cual hay un registro para los códigos de estado HTTP.
Julian Reschke
26
No estoy de acuerdo con 507este propósito. Mi interpretación 507es que el servidor no tiene espacio, no que la cuenta no tiene espacio.
Patrick
12
Estoy de acuerdo con Patrick 5xxlos errores son por errores relacionados con el servidor.
Sean
10
418: "Soy una tetera", lo que implica que el espacio de almacenamiento es demasiado pequeño (como una tetera es pequeño) en lugar de grande y, por lo tanto, no tiene espacio.
Steve Konves
22

Como otros han señalado, tener una entidad de respuesta en un código de error es perfectamente permisible.

Recuerde que los errores 5xx son del lado del servidor, es decir, el cliente no puede cambiar nada a su solicitud para que la solicitud sea aprobada. Si se supera la cuota del cliente, definitivamente no se trata de un error del servidor, por lo que debe evitarse 5xx.

SerialSeb
fuente
No estaría de acuerdo. La Cuota excedida sería un error del servidor (5xx) porque: La solicitud del cliente es válida y habría tenido éxito si estuviera dentro de la cuota, lo que descarta la serie 400.
mikek3332002
44
Pero el servidor no ha hecho nada malo.
Charlie Schliesser
19

Hay dos tipos de errores. Errores de aplicación y errores HTTP. Los errores HTTP son solo para informarle a su controlador AJAX que las cosas salieron bien y no deberían usarse para otra cosa.

5xx Error del Servidor

500 Internal Server Error
501 Not Implemented
502 Bad Gateway
503 Service Unavailable
504 Gateway Timeout
505 HTTP Version Not Supported
506 Variant Also Negotiates (RFC 2295 )
507 Insufficient Storage (WebDAV) (RFC 4918 )
509 Bandwidth Limit Exceeded (Apache bw/limited extension)
510 Not Extended (RFC 2774 )

2xx éxito

200 OK
201 Created
202 Accepted
203 Non-Authoritative Information (since HTTP/1.1)
204 No Content
205 Reset Content
206 Partial Content
207 Multi-Status (WebDAV)

Sin embargo, la forma en que diseñe los errores de su aplicación depende realmente de usted. Desbordamiento de pila, por ejemplo, envía un objeto con response, datay messagepropiedades. La respuesta que creo contiene trueo falsepara indicar si la operación fue exitosa (generalmente para operaciones de escritura). Los datos contienen la carga útil (generalmente para operaciones de lectura) y el mensaje contiene metadatos adicionales o mensajes útiles (como mensajes de error cuando responsees false).

aleemb
fuente
2
400 también es útil para indicar un problema en la aplicación cliente.
dolmen
19

Sé que esto es extremadamente tarde para la fiesta, pero ahora, en el año 2013, tenemos algunos tipos de medios para cubrir el manejo de errores de una manera distribuida común (RESTful). Consulte "vnd.error", application / vnd.error + json ( https://github.com/blongden/vnd.error ) y "Detalles del problema para las API HTTP", application / problem + json ( https: // tools. ietf.org/html/draft-nottingham-http-problem-05 ).

Jørn Wildt
fuente
2
Gracias por los enlaces. draft-nottingham-http-problem ahora es un estándar propuesto: datatracker.ietf.org/doc/rfc7807
seanf
9

Convenido. La filosofía básica de REST es utilizar la infraestructura web. Los códigos de estado HTTP son el marco de mensajería que permite a las partes comunicarse entre sí sin aumentar la carga de HTTP. Ya son códigos universales establecidos que transmiten el estado de respuesta y, por lo tanto, para ser verdaderamente RESTANTES, las aplicaciones deben usar este marco para comunicar el estado de respuesta.

Enviar una respuesta de error en un sobre HTTP 200 es engañoso y obliga al cliente (consumidor de API) a analizar el mensaje, muy probablemente de manera no estándar o propietaria. Esto tampoco es eficiente: obligará a sus clientes a analizar la carga HTTP cada vez para comprender el estado de respuesta "real". Esto aumenta el procesamiento, agrega latencia y crea un entorno para que el cliente cometa errores.

Kingz
fuente
3
Ya sea que tenga una respuesta exitosa o una respuesta fallida, lo más probable es que analice la respuesta. Si es un error, desea analizarlo para obtener el mensaje de error. Las respuestas de error son generalmente pequeñas y rápidas de analizar. No creo que debamos preocuparnos por tratar de optimizar para evitar analizar las respuestas de error. ¿Desecharías la respuesta de error sin analizarla? Imprudente en mi opinión.
AgilePro
3
Si obtiene un 200 OK, puede elegir no analizarlo también, dependiendo de las reglas de su negocio. El punto no es si lo analizamos en todo momento o no. El punto es la intención: ¿cuál es la intención de 200 OK? Está dañando la intención al enviar mensajes de error envueltos en 200 OK.
Kingz
1
"¿Cuál es la intención de 200 OK?" - indicando el éxito de la capa de transporte. La solicitud se recibió y respondió con éxito, solo había un problema específico de la aplicación que no tenía nada que ver con HTTP. +++ Dicho al revés: el envío de 404 en el mundo REST significa que no se encontró algo , tal vez la URL es simplemente incorrecta o el recurso a procesar o cualquier otra cosa no se encontró. Sin analizar el mensaje, no puedes. IMHO REST solo está combinando capas.
maaartinus
La fusión es la norma. Le proporciona una sintaxis para tratar que se adapta a su línea de razonamiento y le permite concentrarse en la capa empresarial. De acuerdo con el transporte, las comunicaciones de estado posteriores, ese es el propósito en primer lugar, REST no fue inventado / propuesto simultáneamente con HTTP, llegó más tarde y simplemente decidió usar la infraestructura existente para representar a los ESTADOS y sus CAMBIOS.
Kingz
5

Por favor, respete la semántica del protocolo. Use 2xx para respuestas exitosas y 4xx, 5xx para respuestas de error, ya sean sus excepciones comerciales u otras. Si el uso previsto de 2xx para cualquier respuesta hubiera sido el caso de uso previsto en el protocolo, no tendrían otros códigos de estado en primer lugar.

rahil008
fuente
3

No olvide los errores 5xx también para los errores de aplicación.

En este caso, ¿qué pasa con 409 (Conflicto)? Esto supone que el usuario puede solucionar el problema eliminando los recursos almacenados.

De lo contrario, 507 (no del todo estándar) también puede funcionar. No usaría 200 a menos que use 200 para errores en general.

Kathy Van Stone
fuente
-2

Si se excede la cuota del cliente, es un error del servidor, evite 5xx en este caso.

anualidad fija
fuente
3
¿Por qué evitar los errores de la serie 5xx cuando son para errores del servidor?
mikek3332002
77
'cuota de cliente excedida' no es un error del servidor en mi humilde opinión, es una restricción del cliente y debe estar por debajo de 4xx.
MyGGaN