Daniel Murillo
Índice

Arquitectura · 20 de octubre de 2026 · Daniel Murillo

REST: cómo diseñar y optimizar una API

REST no vuelve rápida a una API por sí solo. Cómo diseñar endpoints, caché, compresión y conexiones antes de cambiar de protocolo.

REST suele ser un excelente punto de partida para una API. Su valor no está en ser siempre el protocolo más rápido, sino en aprovechar un modelo sencillo, interoperable y compatible con las capacidades de HTTP.

Introducción

Elegir una tecnología de comunicación no consiste en encontrar un ganador universal. Consiste en entender qué necesita el sistema, qué recursos consume y qué complejidad estamos dispuestos a mantener.

REST es una opción sólida para aplicaciones web, móviles, integraciones y servicios públicos porque utiliza conceptos conocidos: recursos, métodos HTTP, códigos de estado, encabezados y URLs. Además, encaja bien con proxies, CDN, herramientas de observabilidad y cachés HTTP.

Pero REST no vuelve rápida a una API por sí solo. Un endpoint puede ser lento por consultas SQL ineficientes, respuestas demasiado grandes, conexiones que se crean repetidamente o dependencias externas que tardan en responder. Antes de migrar a otra tecnología, conviene encontrar el cuello de botella.

1. Qué es REST y por qué existe

REST significa Representational State Transfer. Es un estilo arquitectónico que organiza la interacción alrededor de recursos identificables y utiliza las semánticas de HTTP.

Por ejemplo:

GET    /api/products/123
POST   /api/products
PATCH  /api/products/123
DELETE /api/products/123

Los métodos expresan la intención de la operación, mientras que los códigos de estado comunican su resultado. Esta uniformidad permite que clientes, servidores, proxies y herramientas compartan expectativas comunes.

REST no obliga a que todos los endpoints sigan exactamente la misma forma, ni exige JSON, aunque JSON sea habitual. Su principal ventaja práctica es que se apoya en una infraestructura ampliamente entendida.

2. Diseñar endpoints útiles

Supongamos que una pantalla necesita mostrar el nombre, precio e imagen de veinte productos. Devolver todos los detalles de cada producto —auditoría, proveedores, historial y relaciones— desperdicia ancho de banda y procesamiento.

Una API puede ofrecer paginación y filtros:

GET /api/products?category=books&limit=20
GET /api/products/123

Cuando existe una necesidad real, también puede permitir proyecciones:

GET /api/products?fields=id,name,price,imageUrl

La proyección de campos es una decisión de diseño, no un requisito de REST. Hay que evitar convertirla en un lenguaje de consulta demasiado complejo si el problema no lo necesita.

Paginación

Para colecciones pequeñas, page y limit pueden ser suficientes. Para conjuntos grandes o que cambian constantemente, una paginación por cursor suele ofrecer una navegación más estable.

GET /api/orders?limit=50&cursor=...

El servidor debe validar el cursor y establecer un límite máximo de resultados. Permitir consultas ilimitadas puede provocar consumo excesivo de memoria, CPU y base de datos.

3. Optimizar el trabajo del servidor

Una respuesta pequeña no garantiza una respuesta rápida. Si el servidor ejecuta una consulta por cada registro relacionado, puede aparecer el problema N+1.

Las medidas habituales incluyen:

  • Revisar planes de ejecución e índices de base de datos.
  • Agrupar consultas cuando sea apropiado.
  • Evitar consultas redundantes.
  • No cargar relaciones que la operación no necesita.
  • Aplicar caché solo cuando los datos puedan reutilizarse correctamente.
  • Medir por separado el tiempo de base de datos, lógica de negocio y serialización.

Si el backend tarda 700 ms esperando una base de datos, reducir el JSON de 20 KB a 10 KB no resolverá la causa principal.

4. Conexiones y versiones de HTTP

Crear una conexión nueva para cada petición puede introducir costes de red y negociación TLS. Reutilizar conexiones y clientes HTTP permite amortizar parte de ese trabajo.

HTTP/2 incorpora multiplexación de solicitudes sobre una conexión y compresión de encabezados. HTTP/3 utiliza QUIC sobre UDP y cambia el comportamiento de los flujos frente a pérdidas de paquetes.

Estas versiones pueden mejorar ciertos patrones de tráfico, pero no son una optimización automática. La latencia geográfica, el tamaño de las respuestas, los intermediarios y el cuello de botella real siguen importando.

Recomendaciones prácticas:

  • Reutilizar clientes HTTP y pools de conexiones.
  • Configurar timeouts explícitos.
  • Cancelar operaciones que ya no se necesitan.
  • Evitar cadenas innecesarias de llamadas entre servicios.
  • Medir HTTP/2 y HTTP/3 en la infraestructura real antes de asumir que una versión es superior.

5. Caché HTTP: una ventaja importante de REST

Las respuestas de recursos pueden aprovechar políticas HTTP bien definidas.

Cache-Control: public, max-age=60
ETag: "product-123-v4"
Vary: Accept-Encoding

Cache-Control expresa la política de almacenamiento. ETag identifica una versión del recurso y permite validaciones condicionales mediante If-None-Match. Si el recurso no ha cambiado, el servidor puede responder 304 Not Modified sin reenviar el cuerpo.

No todas las respuestas deben ser públicas. Los datos personales, las respuestas dependientes de permisos y el contenido sensible requieren políticas adecuadas. La caché debe considerar autenticación, variaciones de contenido e invalidación.

6. Compresión sin malgastar CPU

Gzip y Brotli pueden reducir respuestas textuales como JSON, HTML, CSS y JavaScript. Zstandard puede ser útil en entornos compatibles, pero no debe asumirse que todos los navegadores y proxies lo aceptan para HTTP.

Para respuestas dinámicas, Gzip en un nivel intermedio —por ejemplo, 5 o 6— es un punto de partida razonable, no una regla universal. Brotli puede comprimir más ciertos contenidos, aunque los niveles altos pueden costar más CPU.

Conviene:

  • Establecer un tamaño mínimo para comprimir.
  • Medir tamaño original, tamaño comprimido y tiempo de compresión.
  • No volver a comprimir imágenes, vídeo y otros formatos ya comprimidos.
  • Verificar si el proxy o CDN ya realiza compresión.
  • Usar Vary: Accept-Encoding cuando corresponda.

7. Recursos estáticos y respuestas dinámicas no son iguales

Los archivos estáticos generados durante el build pueden precomprimirse con Gzip o Brotli. Así, el servidor entrega el archivo comprimido sin repetir el trabajo en cada solicitud.

assets/
├── app.js
├── app.js.gz
└── app.js.br

El servidor o CDN debe negociar correctamente la variante según Accept-Encoding.

Los recursos versionados por contenido pueden tener una caché prolongada:

Cache-Control: public, max-age=31536000, immutable

Esto es apropiado si el nombre del archivo cambia cuando cambia su contenido. Para respuestas dinámicas de API, en cambio, la compresión suele ocurrir durante la petición y su coste de CPU afecta a la latencia.

8. Cuándo elegir REST

REST suele ser una buena opción cuando:

  • Los recursos y operaciones del dominio son claros.
  • Se necesita una API pública o consumida por distintos clientes.
  • La interoperabilidad importa.
  • Se quiere aprovechar HTTP, CDN, caché y herramientas maduras.
  • La complejidad de GraphQL o gRPC no aporta un beneficio suficiente.

Puede no ser la mejor herramienta para cada problema: las interfaces con necesidades de datos muy variables pueden beneficiarse de GraphQL; la comunicación interna con contratos estrictos puede encajar con gRPC; y los eventos bidireccionales continuos pueden requerir WebSockets.

9. Cómo decidir con datos

Mide latencia p50, p95 y p99, throughput, errores, CPU, memoria, bytes transferidos y tiempo de base de datos. Compara caché fría y caliente, conexiones nuevas y reutilizadas, respuestas comprimidas y sin comprimir.

Un benchmark justo compara la misma operación, los mismos datos y condiciones equivalentes. No es válido comparar una implementación REST sin optimizar con otra tecnología cuidadosamente afinada.

Conclusión

REST es un punto de partida pragmático porque es interoperable, conocido y aprovecha capacidades HTTP maduras. La mayor mejora suele venir de eliminar trabajo innecesario, reducir viajes de red, optimizar consultas y configurar bien caché y compresión.

Antes de migrar una API, mide qué la hace lenta. Optimiza la causa real y cambia de modelo de comunicación cuando exista una necesidad concreta que lo justifique.

En esta serie

  1. REST: cómo diseñar y optimizar una API (esta nota)
  2. REST vs GraphQL
  3. gRPC vs REST
  4. WebSockets, SSE y Webhooks
  5. Caché y compresión
  6. Benchmarks y decisiones de arquitectura

Referencias