Mensajes de Error Estructurados para APIs HTTP

Nicolas Fränkel

Nicolas Fränkel

November 2, 2022

Technology

Desde que comencé a trabajar en el proyecto Apache APISIX, he estado intentando mejorar mi conocimiento y comprensión de las APIs REST RESTful HTTP. Para ello, estoy leyendo y viendo las siguientes fuentes:

  • Libros. En este momento, estoy terminando API Design Patterns. Esperen una reseña pronto.
  • YouTube. Recomendaría el canal de ErikWilde. Aunque algunos videos son mejores que otros, todos se centran en APIs.
  • IETF RFCs. La mayoría de los RFCs no tratan sobre APIs, pero una persona amable compiló una lista de los que sí lo hacen.

Hoy, me gustaría presentar el RFC "Problem Details for HTTP APIs", también conocido como RFC 7807.

El(los) problema(s)

Los principios REST exigen usar el estado HTTP para comunicarse. Para los errores, HTTP define dos rangos: errores del cliente, 4xx, y errores del servidor, 5xx.

Imaginen una API bancaria que permite realizar transferencias. Debería fallar si intentas transferir más fondos de los que tienes en tu cuenta. Un par de códigos de estado HTTP podrían encajar:

  • 400 Bad Request: El servidor no puede o no procesará la solicitud debido a algo que se percibe como un error del cliente.
  • 402 Payment Required: La solicitud no puede procesarse hasta que el cliente realice un pago. Sin embargo, no existe una convención de uso estándar, y diferentes entidades lo usan en otros contextos.
  • 409 Conflict: La solicitud entra en conflicto con el estado actual del recurso objetivo.

Aquí está el primer problema: los códigos de estado HTTP se especificaron para interacciones humano-máquina a través de navegadores, no para interacciones máquina-máquina a través de APIs. Por lo tanto, seleccionar un código de estado que se corresponda uno a uno con el caso de uso rara vez es sencillo. Para el registro, Martin Fowler parece favorecer el 409 en nuestro caso.

Cualquiera que sea el código de estado, el segundo problema se refiere a la carga útil del error o, más precisamente, a su estructura. La estructura no es importante si una sola organización gestiona el cliente y el proveedor de la API. Incluso si un equipo dedicado desarrolla cada uno de ellos, pueden alinearse. Por ejemplo, imaginen una aplicación móvil que llama a su propia API.

Sin embargo, surgen problemas cuando un equipo decide usar una API de terceros. La elección de la estructura de respuesta es significativa en este caso porque ahora se considera parte de un contrato: cualquier cambio por parte del proveedor puede romper los clientes. Peor aún, es probable que la estructura sea diferente de un proveedor a otro.

Por lo tanto, una estructura estandarizada de informes de errores:

  • Proporciona uniformidad entre los proveedores
  • Aumenta la estabilidad de la API

RFC 7807

RFC 7807 tiene como objetivo resolver el problema proporcionando una estructura de error estandarizada.

La estructura es la siguiente:

Estructura

El RFC describe los campos:

  • "type" (string) - Una referencia URI [RFC3986] que identifica el tipo de problema. Esta especificación alienta a que, cuando se desreferencie, proporcione documentación legible por humanos para el tipo de problema (e.g., usando HTML [W3C.REC-html5-20141028]). Cuando este miembro no está presente, se asume que su valor es "about:blank".
  • "title" (string) - Un resumen breve y legible por humanos del tipo de problema. NO DEBERÍA cambiar de una ocurrencia a otra del problema, excepto con fines de localización (e.g., usando negociación de contenido proactiva; ver [RFC7231, Sección 3.4]).
  • "status" (number) - El ([RFC7231], Sección 6) generado por el servidor de origen para esta ocurrencia del problema.
  • "detail" (string) - Una explicación legible por humanos específica para esta ocurrencia del problema.
  • "instance" (string) - Una referencia URI que identifica la ocurrencia específica del problema. Puede o no proporcionar más información si se desreferencia.

-- Miembros de un Objeto de Detalles de Problema

El RFC ofrece el siguiente ejemplo cuando no hay suficientes fondos para realizar una transferencia bancaria.

Ejemplo del RFC

Un ejemplo

Usaré uno de mis demos existentes como ejemplo. El demo destaca varios pasos para facilitar el proceso de evolución de tus APIs.

En el paso 6, quiero que los usuarios se registren, por lo que limito el número de llamadas en una ventana de tiempo si no están autenticados. He creado un plugin dedicado de Apache APISIX para esto. Después de que se haya alcanzado el límite de llamadas, devuelve:

HTTP/1.1 429 Too Many Requests
Date: Fri, 28 Oct 2022 11:56:11 GMT
Content-Type: text/plain; charset=utf-8
Transfer-Encoding: chunked
Connection: keep-alive
Server: APISIX/2.15.0

{"error_msg":"Por favor, regístrese en https:\/\/apisix.org\/register para obtener su token de API y disfrutar de llamadas ilimitadas"}

Estructuraremos el mensaje según el RFC 7807.

Reglas del RFC 7807

Conclusión

El RFC 7807 no solo ayuda a los desarrolladores de clientes. Es una gran ayuda para los implementadores de APIs, ya que proporciona pautas rápidas para evitar reinventar la rueda en cada proyecto.

Para más información:

Publicado originalmente en A Java Geek el 30 de octubre de 2022

Tags: