Ilustración editorial: Patrones de Estructura de Respuestas API: Cuándo HAL, JSON:API y HATEOAS Realmente Importan

Diseño de API · REST · HATEOAS · HAL · JSON:API · Patrones de Respuesta · Hipermedia

Patrones de Estructura de Respuestas API: Cuándo HAL, JSON:API y HATEOAS Realmente Importan

Una guía práctica para elegir entre simples envolventes JSON, HAL, JSON:API y HATEOAS para equipos pequeños que construyen APIs. Entiende los compromisos, no el hype.

Publicado:

La Respuesta Corta

Para la mayoría de los proyectos independientes y equipos pequeños, un envolvente JSON limpio y consistente es la opción correcta. HATEOAS, HAL y JSON:API no son incorrectos — resuelven problemas reales — pero añaden complejidad que raramente compensa hasta que tu API tiene múltiples consumidores, un ciclo de vida largo y un equipo capaz de sostener la sobrecarga. Si estás construyendo una API de producto único para tu frontend o una integración pequeña con un socio, estandariza la forma de tu respuesta y sigue adelante.

Por Qué la Estructura de Respuesta Importa Más de lo que Piensas

Cada respuesta de API es un contrato. Cuando ese contrato cambia de forma de un endpoint a otro, los consumidores pagan un impuesto: lógica de análisis adicional, manejo de errores frágil y documentación que se desvía de la realidad. El modo de fallo más común no es una funcionalidad faltante sino la inconsistencia: un endpoint devuelve datos dentro de una clave data, otro los devuelve planos, y los errores aparecen como cadenas en algunos lugares y como objetos en otros.

Las plataformas líderes evitan esto aplicando una estructura de respuesta uniforme. Stripe, Google Cloud APIs y GitHub siguen patrones predecibles para que los clientes puedan escribir código de integración genérico una vez y reutilizarlo en todas partes. La lección para equipos pequeños es simple: decide una forma de respuesta temprano, documentala y cúmplela.

Los Tres Patrones que Debes Conocer

1. Envolvente JSON Simple

Un envolvente JSON envuelve los datos de tu recurso dentro de una estructura predecible. Una respuesta de éxito típica se ve así:

{
  "status": "success",
  "data": {
    "id": "order_12345",
    "amount": 2500,
    "customer_id": "cust_789"
  }
}

Y una respuesta de error sigue la misma forma:

{
  "status": "error",
  "error": {
    "code": "PAYMENT_FAILED",
    "message": "Payment was declined by the issuer"
  }
}

Esto es lo que la mayoría de las APIs pequeñas deberían buscar. La estructura es fácil de analizar, fácil de documentar y fácil de probar. Ganas predictibilidad sin añadir una capa de navegación hipermediática.

2. HAL (Hypertext Application Language)

HAL es un formato basado en JSON que añade una sección _links a cada representación de recurso. Fue diseñado para hacer las APIs REST más descubribles incrustando enlaces de navegación directamente en las respuestas. Una respuesta HAL para un pedido se ve así:

{
  "_links": {
    "self": { "href": "/orders/123" },
    "customer": { "href": "/customers/789" },
    "next": { "href": "/orders?cursor=abc" }
  },
  "_embedded": {
    "customer": {
      "id": "cust_789",
      "name": "Acme Corp"
    }
  },
  "id": "order_12345",
  "amount": 2500
}

La sección _links actúa como una tabla de navegación. En lugar de codificar URLs como /customers/17/orders en tu código cliente, el cliente lee la relación customer desde _links y la sigue. Esto reduce el acoplamiento cliente-servidor porque el servidor controla el URI de destino detrás de cada relación, y ambos lados pueden evolucionar de forma más independiente.

HAL también soporta recursos incrustados a través de _embedded, lo que te permite anidar datos relacionados en una sola respuesta en lugar de hacer múltiples idas y vueltas. Esto es útil cuando sabes que tus clientes siempre necesitarán el recurso relacionado junto con el padre.

Frameworks como Spring HATEOAS hacen que producir respuestas HAL sea directo. Por defecto, Spring Boot serializa modelos en application/hal+json cuando el cliente envía un encabezado Accept para ese tipo de medio. También puedes configurarlo para devolver HAL por defecto para todas las respuestas JSON, o deshabilitar ese comportamiento con spring.hateoas.use-hal-as-default-json-media-type=false.

3. HATEOAS (Hypermedia as the Engine of Application State)

HATEOAS se confunde a menudo con HAL, pero no son lo mismo. HAL es un formato. HATEOAS es una restricción arquitectónica de REST que dice que los clientes deben interactuar con una aplicación únicamente a través de hipermedia proporcionada por el servidor. En una API compatible con HATEOAS, cada respuesta identifica recursos relacionados y transiciones de estado válidas actualmente a través de relaciones de enlace.

La idea clave es que el cliente no necesita conocimiento previo de cada URI de endpoint. Comienza desde un punto de entrada, entiende el tipo de medio y descubre interacciones subsiguientes dinámicamente a través de los enlaces en cada respuesta. Por ejemplo, una respuesta de pedido podría incluir relaciones para self, cancel_order y track_shipment. El cliente elige una relación disponible en lugar de construir la siguiente URL él mismo.

Este enfoque tiene beneficios reales para la evolucionabilidad de la API. Cuando añades una nueva transición de estado o cambias la ruta de un endpoint, solo necesitas actualizar los enlaces en la respuesta. Los clientes que siguen HATEOAS descubrirán el cambio automáticamente. Los clientes que codifican URLs en duro se romperán.

Spring Boot 3.5.4 y Spring HATEOAS soportan HAL-FORMS, que extiende HAL con affordances — representaciones de formularios que describen cómo realizar acciones como crear o actualizar recursos. Esto hace que la API sea aún más autodescriptiva, porque el cliente puede ver no solo qué enlaces existen sino qué entradas requiere cada acción.

4. JSON:API

JSON:API es una especificación que define una estructura estricta de cómo los datos deben serializarse y deserializarse. Requiere una forma específica de nivel superior con claves data, errors, meta y links. También define reglas para filtrado, ordenamiento, paginación e inclusión de relaciones a través de parámetros de consulta como ?include=customer.

JSON:API es el más opinativo de los tres patrones. Fuerza la consistencia pero también te obliga a conformarte a sus convenciones. Esto puede ser una fortaleza cuando tienes muchos consumidores que necesitan un contrato predecible, pero puede sentirse pesado para una API pequeña con un solo consumidor.

Cuándo Usar Cada Patrón

Usa un Envolvente JSON Simple Cuando:

Un envolvente JSON consistente con formas claras de éxito y error es suficiente para la mayoría de los proyectos independientes. La predictibilidad que ganas de la estandarización vale más que la descubribilidad que obtendrías de enlaces hipermediáticos.

Usa HAL Cuando:

HAL te da descubribilidad con sobrecarga relativamente baja. Las secciones _links y _embedded añaden estructura sin requerir que los clientes entiendan una especificación completa.

Usa HATEOAS Cuando:

HATEOAS brilla en APIs de larga duración y múltiples consumidores donde el costo de las URLs codificadas en duro se vuelve doloroso. Es menos útil para un equipo pequeño construyendo una API de producto único.

Usa JSON:API Cuando:

Los Compromisos que No Debes Ignorar

Cada patrón de estructura de respuesta implica un compromiso entre predictibilidad y flexibilidad, entre simplicidad y descubribilidad.

Un envolvente JSON simple es predecible pero no autodescriptivo. Los clientes deben conocer la estructura de endpoints con anticipación. HAL añade descubribilidad pero requiere que los clientes entiendan relaciones de enlace y la estructura _links / _embedded. HATEOAS añade navegabilidad completa pero requiere que los clientes sean conscientes de hipermedia, algo que muchos consumidores móviles y basados en scripts no son. JSON:API añade la mayor estructura y la mayor curva de aprendizaje.

También existe un costo de mantenimiento. Los formatos hipermediáticos requieren que tu backend genere y mantenga relaciones de enlace, maneje recursión en relaciones bidireccionales y asegure que las affordances se mantengan sincronizadas con tu lógica de negocio. Si tu equipo es de dos o tres personas, esa carga de mantenimiento es real.

Una Recomendación Práctica

Comienza con un envolvente JSON simple y consistente. Define tus formas de éxito y error, documéntalas y aplícalas con una guía de estilo o un linter. Si tu API crece y encuentras que los consumidores están constantemente codificando URLs en duro que se rompen cuando refactorizas, esa es la señal para añadir enlaces HAL. Si luego encuentras que los clientes necesitan descubrir transiciones de estado válidas dinámicamente, esa es la señal para avanzar hacia HATEOAS.

No adoptes un formato hipermediático porque está de moda. Adóptalo porque tienes un problema específico que resuelve mejor que una alternativa más simple. La mejor estructura de respuesta de API es la que tu equipo puede mantener consistentemente con el tiempo.

FAQ

¿Es HATEOAS requerido para que una API REST sea verdaderamente RESTful?

Técnicamente sí — HATEOAS es una de las seis restricciones en la tesis original de REST de Roy Fielding. En la práctica, la mayoría de las APIs llamadas REST no lo implementan, y eso no las hace inútiles. Las hace más simples. Si tu API funciona para tus consumidores, el debate de pureza arquitectónica es académico.

¿Puedo mezclar enlaces HAL con un envolvente JSON simple?

Sí. Puedes comenzar con una respuesta JSON plana y añadir una sección _links a endpoints específicos que se beneficien de la descubribilidad. Este enfoque incremental te permite adoptar hipermedia donde añade valor sin reestructurar toda tu API.

¿HATEOAS ralentiza las respuestas de la API?

No significativamente. Los datos de enlace adicionales son pequeños — usualmente unos pocos cientos de bytes por respuesta. El costo real está en el tiempo de desarrollo, no en el tamaño de la respuesta. Generar y mantener relaciones de enlace requiere código adicional y pruebas.

¿Deberían las aplicaciones móviles usar HATEOAS?

Generalmente no. Los clientes móviles tienden a preferir respuestas predecibles y planas que son fáciles de analizar y almacenar en caché. HATEOAS añade complejidad que los equipos móviles a menudo no necesitan. Un envolvente JSON bien estructurado con documentación clara de endpoints es usualmente la mejor opción para consumidores móviles.

¿Cuál es la diferencia entre HAL y JSON:API?

HAL es un formato ligero enfocado en enlaces y recursos incrustados. JSON:API es una especificación integral que cubre serialización, filtrado, ordenamiento, paginación y manejo de errores. HAL es más fácil de adoptar de forma incremental. JSON:API es más rígido pero más poderoso para consultas complejas.

Fuentes