«REST está muerto, hay que hacerlo todo en GraphQL». Llevamos una década escuchándolo, y mientras tanto la inmensa mayoría de las APIs que mueven el mundo — Stripe, GitHub, Twilio — siguen siendo REST... o son GraphQL. El debate está mal planteado: no son rivales, son herramientas que resuelven problemas distintos.
La pregunta correcta no es «¿cuál es mejor?» sino «¿qué problema tengo delante?». En esta guía te damos el marco de decisión que usamos en HexagonalGuru cuando diseñamos una API para un cliente: sin hype, con los costes reales de cada opción.
El Problema: Elegir por Moda
Hemos auditado proyectos con GraphQL montado sobre tres tablas CRUD (un cañón para matar moscas, con su N+1 incluido) y aplicaciones móviles consumiendo doce endpoints REST para pintar una sola pantalla. En ambos casos el equipo pagó un precio: complejidad innecesaria o rendimiento pobre. Elegir por moda en lugar de por problema es deuda técnica desde el primer commit.
REST en Esencia
REST modela la API como recursos (/usuarios/42, /pedidos) manipulados con los verbos HTTP. Sus fortalezas llevan veinte años demostradas:
- Simplicidad y predictibilidad. Cualquier desarrollador entiende
GET /pedidos/42sin documentación. - Caché HTTP gratis. CDNs, proxies y navegadores cachean respuestas GET con cabeceras estándar. Es la forma más barata de escalar lecturas que existe.
- Ecosistema maduro. OpenAPI, generadores de clientes, herramientas de testing, monitorización por endpoint — todo está inventado.
- Códigos de estado semánticos. Un 404 es un 404. Un 429 es un 429. La infraestructura (balanceadores, WAFs, dashboards) los entiende.
GraphQL en Esencia
GraphQL expone un único endpoint y un esquema tipado; el cliente pide exactamente los campos que necesita en una sola consulta:
Sus fortalezas reales:
- Adiós al overfetching y underfetching. El cliente recibe lo que pide, ni un campo más ni una petición menos. En móvil, con redes malas, se nota.
- Un esquema como contrato vivo. Introspección, autocompletado y validación de consultas contra el esquema. La documentación no se desincroniza porque es el esquema.
- Frontends independientes. Web, iOS y Android piden formas distintas de los mismos datos sin pedir cambios al backend. Brilla como capa BFF (Backend for Frontend).
Lo Que Nadie Te Cuenta de GraphQL
GraphQL no es gratis. Estos son los costes que vemos una y otra vez en las auditorías:
- El N+1 de los resolvers. Una consulta anidada inocente puede disparar cientos de queries a la base de datos. Sin dataloaders (batching), tu GraphQL es un generador de problemas de rendimiento.
- La caché se complica. Todo es un
POSTal mismo endpoint: la caché HTTP deja de funcionar. Toca reinventarla (persisted queries con GET, caché a nivel de campo, TTLs en el esquema). - Rate limiting por complejidad. Ya no basta contar peticiones: una sola consulta puede costar mil veces más que otra. Necesitas límites de profundidad y de coste de consulta.
- Errores con 200 OK. Las respuestas de error llegan con HTTP 200 y un array
errorsdentro. Tus dashboards y alertas necesitan adaptarse. - Curva de aprendizaje y tooling. Esquema, resolvers, dataloaders, fragmentos, generación de código en cliente... es otra capa de conocimiento que el equipo debe dominar.
El Mismo Ejemplo en Ambos Mundos
Una pantalla de perfil con los pedidos del usuario. En REST, el cliente orquesta:
GET /usuarios/42
GET /usuarios/42/pedidos?limit=5
GET /productos/101
Cada respuesta trae todos sus campos (overfetching) y el cliente encadena peticiones (underfetching). En GraphQL, una sola consulta declara la forma exacta:
query {
usuario(id: 42) {
nombre
pedidos(limit: 5) {
id
total
lineas { producto { nombre } cantidad }
}
}
}
Una petición, cero campos de sobra. ¿A cambio? El backend debe resolver esa consulta sin convertirla en un festival de N+1:
// Resolver con dataloader: una query por lote, no una por pedido
public function lineas(array $pedidoIds): array
{
$lineas = $this->lineas->buscarPorPedidos($pedidoIds); // 1 query
return array_map(fn ($id) => $lineas[$id] ?? [], $pedidoIds);
}
Cómo Decidir: El Marco Práctico
Elige REST cuando:
- Tu API es un CRUD razonablemente directo o sirve recursos estables y predecibles.
- La caché HTTP y el CDN son parte de tu estrategia de rendimiento (contenido público, catálogos).
- Tus consumidores son terceros o integraciones servidor-a-servidor: REST con OpenAPI es el denominador común que todo el mundo sabe consumir.
- El equipo es pequeño y no necesita otra tecnología que mantener.
Elige GraphQL cuando:
- Tienes varios clientes (web, móvil, partners) que necesitan formas de datos muy distintas sobre el mismo dominio.
- Tus pantallas agregan datos de muchas entidades y el overfetching te está costando rendimiento real en móvil.
- Actúa como capa de agregación (BFF) sobre varios servicios internos: el cliente pide una consulta, GraphQL orquesta.
- Tienes equipo con capacidad de operar sus particularidades (dataloaders, persisted queries, límites de complejidad).
Y la respuesta que más veces es la correcta en sistemas grandes: los dos. REST para integraciones y recursos cacheables, GraphQL como BFF para las apps. Conviven sin problema.
Errores Comunes
- GraphQL como proxy directo de la base de datos. Resolvers que ejecutan una query por campo, sin dataloaders. El rendimiento se hunde exactamente cuando más tráfico tienes.
- Exponer GraphQL públicamente sin límites. Sin límite de profundidad ni de complejidad, cualquiera puede tumbar tu API con una consulta recursiva.
- REST sin oficio. Colecciones sin paginación, respuestas sin filtrar campos, cero versionado y errores que siempre devuelven 500. El problema no era REST.
- GraphQL para un CRUD simple. Si tu API son cuatro entidades planas y un solo cliente, estás pagando el coste sin cobrar el beneficio.
- Elegir antes de medir. Si no sabes cuántas peticiones hacen tus pantallas hoy, no sabes si tienes un problema de overfetching o de otro tipo.
En Resumen
REST y GraphQL no compiten: resuelven problemas distintos. REST gana en simplicidad, caché e integraciones; GraphQL gana cuando varios clientes necesitan formas de datos diferentes y el overfetching duele de verdad. Decide a partir de tus clientes, tu dominio y la capacidad de tu equipo — no del artículo de moda.
¿Estás diseñando una API o heredaste una que no rinde como debería? En nuestras auditorías medimos el comportamiento real (peticiones por pantalla, N+1, caché) y te entregamos un plan concreto. Solicita una consultoría gratuita →
Sigue leyendo: Rendimiento web: guía práctica para acelerar tu aplicación.