REST es una arquitectura sin estado en la que los clientes pueden acceder y manipular recursos en un servidor. En general, los servicios REST utilizan HTTP para anunciar un conjunto de recursos que administran y proporcionan una API que permite a los clientes obtener o alterar el estado de estos recursos.

En este tutorial, aprenderemos sobre algunas de las mejores prácticas para manejar errores de API REST, incluidos enfoques útiles para proporcionar a los usuarios información relevante, ejemplos de sitios web a gran escala y una implementación concreta usando una aplicación Spring REST de ejemplo.

Códigos de estado http

Cuando un cliente realiza una solicitud a un servidor HTTP, y el servidor recibe la solicitud con éxito, el servidor debe notificar al cliente si la solicitud se manejó con éxito o no. HTTP logra esto con cinco categorías de códigos de estado:

  • 1xx : el servidor reconoce una solicitud
  • 2xx (correcto): el servidor completó la solicitud como se esperaba
  • 3xx (redirección): el cliente debe realizar más acciones para completar la solicitud
  • 4xx (error del cliente): el cliente envió una solicitud no válida
  • 5xx (error del servidor): el servidor no pudo cumplir una solicitud válida debido a un error con el servidor

Manejo de errores

El primer paso en el manejo de errores es proporcionar a un cliente un código de estado adecuado. Además, es posible que necesitemos proporcionar más información en el cuerpo de respuesta.

Respuestas básicas

La forma más sencilla de manejar los errores es responder con un código de estado apropiado.

Algunos códigos de respuesta comunes incluyen:

  • 400 Solicitud incorrecta: el cliente envió una solicitud no válida, como la falta de un cuerpo o parámetro de solicitud requerido
  • 401 No autorizado: el cliente no pudo autenticarse con el servidor
  • 403 Prohibido: el cliente se autenticó pero no tiene permiso para acceder al recurso solicitado
  • 404 no encontrado: el recurso solicitado no existe
  • 412 Precondición fallida: una o más condiciones en los campos de encabezado de solicitud evaluados como falsos
  • 500 Internal Server Error: se produjo un error genérico en el servidor
  • 503 Servicio no disponible: el servicio solicitado no está disponible

En general, no debemos exponer 500 errores a los clientes. 500 errores indican que se produjo algún problema en el servidor, como una excepción inesperada en nuestro servicio REST al manejar una solicitud. Por lo tanto, este error interno no es asunto de nuestro cliente.

En cambio, deberíamos tratar diligentemente de manejar o detectar errores internos y responder con una respuesta de nivel 400. Por ejemplo, si ocurre una excepción porque no existe un recurso solicitado, deberíamos exponerlo como un error 404, no un error 500.

Si bien son básicos, estos códigos permiten al cliente comprender la naturaleza general del error que ocurrió. Por ejemplo, sabemos que si recibimos un error 403, nos faltan permisos para acceder al recurso que solicitamos.

Sin embargo, en muchos casos, necesitamos proporcionar detalles suplementarios en nuestras respuestas.

Respuestas de error por defecto en spring framework

Estos principios son tan ubicuos que Spring los ha codificado en su mecanismo predeterminado de manejo de errores.

Para demostrarlo, supongamos que tenemos una aplicación Spring REST simple que administra libros, con un endpoint para recuperar un libro por su ID:

curl -X GET -H "Accept: application/json" http://localhost:8080/api/libros/1

Si no hay un libro con un ID de 1, esperamos que nuestro controlador arroje una LibroNoEncontradoException. Al realizar un GET en este punto final, vemos que se lanzó esta excepción y el cuerpo de respuesta es:

{
    "timestamp":"2019-09-16T22:14:45.624+0000",
    "status":500,
    "error":"Internal Server Error",
    "message":"No message available",
    "path":"/api/libros/1"
}

Tenga en cuenta que este controlador de errores predeterminado incluye una marca de tiempo de cuándo ocurrió el error, el código de estado HTTP, un título (el campo de error), un mensaje (que está en blanco de forma predeterminada) y la ruta de URL donde ocurrió el error.

Estos campos proporcionan información a un cliente o desarrollador para ayudar a solucionar el problema y también constituyen algunos de los campos que conforman los mecanismos estándar de manejo de errores.

Además, tenga en cuenta que Spring devuelve automáticamente un código de estado HTTP de 500 cuando se lanza nuestra LibroNoEncontradoException. Aunque algunas API devolverán un código de estado 500, o un código de estado 400, como veremos con las API de Facebook y Twitter, para todos los errores por simplicidad, es mejor usar el código de error más específico cuando sea posible.

Errores mas detallados

Como se ve en el ejemplo de Spring anterior, a veces un código de estado no es suficiente para mostrar los detalles del error. Cuando sea necesario, podemos usar el cuerpo de la respuesta para proporcionar al cliente información adicional. Al proporcionar respuestas detalladas, debemos incluir:

  • Error: el tipo de error que estamos contestando
  • Message: Una descripción general de que es el error
  • Detail: El detalle de porque sucedió ese error.

Por ejemplo si un cliente nos envía una solicitud para un recurso restringido, podemos contestar algo como:

{
    "error": "no-autorizado",
    "message": "El password o usuario son incorrectos",
    "detail": "Por favor asegúrese de que sus credenciales son correctas."
}

Conclusión

En este artículo, examinamos algunas de las mejores prácticas de manejo de errores de API REST, que incluyen:

  • Proporcionar códigos de estado específicos.
  • Incluir información adicional en los organismos de respuesta.
  • Manejo de excepciones de manera uniforme

Si bien los detalles del manejo de errores variarán según la aplicación, estos principios generales se aplican a casi todas las API REST y deben respetarse cuando sea posible.

Esto no solo permite que los clientes manejen los errores de manera consistente, sino que también simplifica el código que creamos al implementar una API REST.

Categorized in:

Tagged in:

, ,