En las conversaciones de kickoff siempre aparece. Alguien del equipo ha leído que GraphQL es «el siguiente paso» y que REST «ya no se usa». La frase suena a criterio técnico. Casi nunca lo es: es una preferencia de DX vestida de arquitectura.
REST vs GraphQL no se decide por modernidad. Se decide por forma del dato, número de clientes, caché, equipo y lo que te va a doler dentro de un año. En un estudio, además, se decide por quién mantiene el contrato cuando el cliente pide la tercera pantalla.
Este artículo es el criterio que usamos en Truman al montar APIs en proyectos de desarrollo web y en apps. Sin guerra de frameworks. Con el coste real de cada opción encima de la mesa.
REST vs GraphQL no es una guerra: es una forma de contrato
REST, bien hecho, es recursos, verbos y representaciones. Un pedido es /orders/1842. Lo lees con GET, lo creas con POST, lo cambias con un contrato predecible. HTTP te da caché, códigos y un ecosistema de proxies que lleva veinte años. GraphQL es un grafo consultable: el cliente pide campos, el servidor resuelve, y el contrato vive en un schema.
Las dos cosas resuelven problemas distintos. REST brilla cuando el recurso es estable y lo consumen pocos clientes con necesidades parecidas. GraphQL brilla cuando hay varios clientes (web, iOS, panel interno) que necesitan recortes distintos del mismo modelo y cuando el coste de abrir un endpoint nuevo por cada pantalla es real.
En un producto como Klapper —web, app y lógica de aforo y cobro— el mapa de datos es amplio: eventos, sesiones, tipos de entrada, pedidos, usuarios. Eso no obliga a GraphQL. Obliga a un modelo claro. Si las pantallas piden siempre el mismo agregado (un evento con sus sesiones), un endpoint REST bien diseñado sobra. Si cada cliente recorta el evento de una manera distinta y el equipo de front no puede esperar a un endpoint nuevo cada sprint, GraphQL entra en la conversación.
Cuándo REST sobra (y es la decisión correcta)
REST sobra —en el sentido de que basta— en la mayoría de webs de cliente que hacemos. Una corporativa con CMS, un portal con cuatro roles, una ficha de servicio que pinta datos de un ERP. El patrón es predecible: listado, detalle, escritura puntual, webhook.
Elige REST cuando se cumple la mayoría de esto: un cliente principal (o dos con las mismas vistas), recursos que puedes nombrar sin sonrojo, necesidad real de caché HTTP (CDN, ETag, Cache-Control), y un equipo que no quiere mantener un runtime de GraphQL, un dataloader y una política de complejidad de queries.
| Señal | REST | GraphQL |
|---|---|---|
| Un cliente, vistas estables | Encaja | Sobrecoste |
| Web + app + panel con recortes distintos | Muchos endpoints | Justificable |
| Caché en CDN / GET público | Nativo | Hay que construirlo |
| Escrituras transaccionales claras | POST/PATCH por caso | Mutations + errores a medida |
| Equipo pequeño, un backend | Menos superficie | Más runtime que mantener |
«REST que sobra» no es REST descuidado. Un GET /events/12?include=sessions,venue o un BFF que agrega tres recursos sigue siendo más barato de operar que un grafo si solo lo usa una web. El problema aparece cuando copias el JSON de la base de datos y lo llamas recurso. Eso no lo arregla cambiar el transport.
Cuándo GraphQL sí justifica la complejidad
GraphQL deja de ser postureo cuando el cuello de botella es el contrato con varios consumidores. En Weddle, un producto digital con app y UX propia, el front suele necesitar recortes que no merecen un endpoint nuevo cada vez: un resumen para la home, un detalle para la ficha, un payload mínimo para una notificación. Si esas formas divergen de verdad, un schema gana a una familia de DTOs sueltos.
También justifica GraphQL un headless con varios frontales —web pública, área privada, app— que leen el mismo CMS o el mismo dominio. Ahí el artículo hermano es cuándo tiene sentido una arquitectura headless: el headless no implica GraphQL, pero si el CMS ya expone un grafo (o tu capa de agregación se parece a uno), no inventes REST por dogma.
¿Estás eligiendo GraphQL porque el cliente pide campos distintos, o porque no quieres diseñar recursos? La segunda razón no se arregla con un schema.
El coste que no sale en el tutorial
GraphQL bien hecho no es «un endpoint /graphql y a correr». Es un schema versionado en la práctica (aunque no tenga número), resolvers que no disparan N+1, persistencia de queries o al menos una lista permitida en producción, timeout y límite de profundidad, y observabilidad de qué campos se piden de verdad. Sin eso, el playground se convierte en una API pública sin forma.
REST mal hecho también es caro: versiones /v3 eternas, breaking changes silenciosos, errores 200 con { "ok": false }. La diferencia es que el ecosistema HTTP te da más suelo. Un GET cacheable en Cloudflare no necesita un talk de conference. Un POST GraphQL cacheable sí.
Tip técnico: si usas GraphQL, persiste las queries en producción
Desactiva la introspección en producción o limítala a un entorno interno. No aceptes queries arbitrarias desde el cliente: un allowlist de documentos persistidos (o un allowlist por hash) evita que alguien te pida el grafo entero y te tumbe la base de datos. En REST el equivalente es no exponer ?include=* sin tope. El principio es el mismo: el cliente no diseña tu carga.
Cómo lo decidimos en un proyecto de estudio
En Truman no hay default ideológico. El default es el más barato de operar para el alcance del año 1. Casi siempre eso es REST (o RPC HTTP con recursos claros) detrás de un monolito razonable. Cuando el producto se trocea de verdad, la conversación deja de ser REST vs GraphQL y pasa a ser monolito o microservicios: dos debates que la gente mezcla y que no se resuelven con la misma herramienta.
El front también condiciona. Un Angular con vistas estables y un store predecible convive bien con REST. Si estás en esa duda de framework, el criterio está en cuándo Angular tiene sentido en 2026. GraphQL no hace mejor a un front desordenado. Le da más cuerda para pedir de más.
GraphQL no es una promoción. Es una hipoteca de complejidad. La firmas cuando el contrato con varios clientes te está costando sprints. No la firmas para que el repo parezca de 2026.
Antes de elegir REST o GraphQL
- ¿Cuántos clientes distintos van a consumir la API en los próximos 12 meses?
- ¿Las pantallas piden recortes distintos del mismo recurso o el mismo agregado una y otra vez?
- ¿Necesitas caché HTTP pública (CDN) o casi todo es dato autenticado y fresco?
- ¿El equipo puede mantener resolvers, dataloaders y límites de complejidad sin un especialista?
- ¿Las escrituras son casos de uso claros (crear pedido, cancelar) o un grafo de mutations sueltas?
- ¿Tienes un plan de autorización por recurso (REST) o por campo (GraphQL) escrito, no «ya se verá»?
- ¿La alternativa más barata (BFF + REST) está descartada por un motivo real, no por moda?
Preguntas frecuentes sobre REST y GraphQL
¿GraphQL es más rápido que REST?
No por sí. Puede reducir overfetch en el cliente y puede empeorar el servidor si cada query dispara N+1. La latencia la marca el modelo, las queries y la red, no el logo de la especificación. Mide el caso, no el hilo de Twitter.
¿Cuándo REST se queda corto en un proyecto de estudio?
Cuando abres un endpoint nuevo por cada pantalla, cuando el mismo recurso tiene cinco representaciones incompatibles, o cuando web y app no pueden compartir contrato sin un BFF que ya es un grafo disfrazado. Ahí GraphQL (o un BFF explícito) deja de ser capricho.
¿Se pueden usar REST y GraphQL en el mismo producto?
Sí. Es habitual: GraphQL para lectura agregada y REST o RPC para webhooks, uploads y operaciones que quieres cachear o firmar como recurso. No mezcles los dos en el mismo caso de uso «por si acaso».
¿Cómo elijo si el cliente ya pide GraphQL en el brief?
Pregunta por qué. Si la respuesta es «el front lo prefiere» y hay un solo cliente, ofrece REST con un contrato OpenAPI y un cliente tipado. Si la respuesta es «tenemos iOS, Android y dos webs», entonces sí, diseña el schema. El brief no es la arquitectura.