- GraphQL busca resolver el problema del exceso de datos solicitados, pero en la mayoría de los entornos empresariales ese problema ya se resolvió de otra forma
- En sistemas corporativos donde la arquitectura BFF (Backend for Frontend) ya es común, la principal ventaja de GraphQL se reduce bastante
- La complejidad de implementación, la menor observabilidad, los problemas de caché, las restricciones de ID y la incomodidad para manejar archivos hacen que el costo aumente en entornos reales de operación
- REST es simple y rápido, y facilita el manejo de errores y el onboarding, por lo que resulta más eficiente en equipos grandes
- En conclusión, GraphQL puede ser útil en situaciones específicas, pero para la mayoría de las empresas es una elección excesiva
El problema que GraphQL intenta resolver
- El objetivo central de GraphQL es evitar el overfetching (solicitar datos innecesarios en exceso)
- El cliente pide solo los campos que necesita, reduciendo la transferencia de datos innecesarios
- Tiene la ventaja de que no hace falta modificar el backend por cada nuevo requerimiento de UI
- Sin embargo, en la práctica esta estructura ideal no encaja bien con una realidad más compleja
El overfetching ya resuelto con BFF
- La mayoría de los frontends empresariales usan una capa BFF (Backend for Frontend)
- Combina datos según la UI, integra múltiples llamadas downstream y oculta la complejidad del backend
- Un BFF basado en REST ya puede devolver solo los datos necesarios, así que la ventaja de GraphQL se vuelve redundante
- Si la capa GraphQL obtiene datos desde APIs REST, el overfetching simplemente se desplaza un nivel hacia abajo
- GraphQL puede ser útil cuando varias páginas comparten el mismo endpoint, pero
- ese beneficio equivale a aceptar más configuración y carga de mantenimiento para ahorrar apenas unos kilobytes
Complejidad de implementación y menor productividad
- GraphQL requiere mucho más tiempo y complejidad de implementación que REST
- Hace falta trabajo adicional para definir esquemas, tipos, resolvers y data sources
- También existe la carga de mantener sincronizados el esquema y el cliente
- GraphQL optimiza el consumo (comodidad del cliente), pero sacrifica la producción (velocidad de desarrollo del servidor)
- En entornos empresariales, la velocidad de desarrollo y la simplicidad suelen ser más importantes
Problemas de observabilidad y monitoreo
- El sistema de códigos de estado HTTP de GraphQL es inconsistente
- Incluso una respuesta 200 puede incluir errores, lo que dificulta distinguir éxito y falla en el monitoreo
- REST separa claramente con 2XX/4XX/5XX, por lo que filtrar en dashboards es más intuitivo
- Se puede personalizar con Apollo y otras herramientas, pero eso agrega configuración extra y carga mental
- Cuando hay incidentes en producción, entender el problema es más difícil y complejo que con REST
Los límites reales del caché
- El normalized caching de Apollo es potente en teoría, pero en la práctica resulta frágil y complejo
- Incluso consultas que solo difieren en un campo se tratan por separado y requieren vinculación manual
- Depurar el caché termina convirtiéndose en un problema aparte
- En cambio, con REST basta con cachear la respuesta completa, lo que lo hace más estable y más fácil de mantener
El problema de las restricciones sobre campos ID
- Apollo asume que todos los objetos necesitan un campo id o _id
- Muchas APIs empresariales no tienen IDs únicos, o no usan identificadores globales
- Para ajustarse a eso, el BFF debe agregar lógica local para generar IDs
- Como resultado, aumentan los campos y la lógica innecesaria, anulando el beneficio de reducir el overfetching
Ineficiencia en la subida y descarga de archivos
- GraphQL no es adecuado para manejar datos binarios
- En la práctica, devuelve una URL de descarga y el archivo se transfiere por REST
- Si se incluyen datos pesados como PDFs en la respuesta GraphQL, el rendimiento empeora
- Por eso, el ideal de una “API única” de GraphQL se rompe
Onboarding y curva de aprendizaje
- La mayoría de los desarrolladores tiene mucha experiencia con REST, pero GraphQL requiere aprendizaje adicional
- Hay que aprender conceptos nuevos como esquemas, resolvers, construcción de queries, reglas de caché y manejo de errores
- Eso reduce la velocidad de onboarding del equipo
- REST, aunque sea “aburrido”, es un enfoque escalable y adecuado para equipos grandes
La complejidad del manejo de errores
- Las respuestas de error en GraphQL son complejas, con campos nullable, partial data, arreglos de errors y códigos de estado extendidos
- Además, hay que rastrear qué resolver fue el que falló
- En REST basta con distinguir 400/500, por lo que es más fácil de entender y depurar
Conclusión: GraphQL es una tecnología de nicho
- GraphQL es una herramienta válida en situaciones específicas
- Pero en la mayoría de los entornos empresariales, el problema ya está resuelto con BFF y REST
- Los desafíos principales no son el overfetching, sino la observabilidad, la confiabilidad y la velocidad
- Como resultado, GraphQL resuelve un problema acotado mientras introduce una complejidad más amplia
- La conclusión es: GraphQL no es malo, pero en la mayoría de los casos no hace falta
2 comentarios
Habrá pros y contras, pero parece mejor diseñar los datos y el control de acceso a nivel de esquema, e ir agregando cosas en la API REST cada vez que se necesita algo, en lugar de terminar devolviéndolo todo después. Tiene desventajas claras, pero también ventajas claras jaja
Comentarios de Hacker News
No estoy de acuerdo con que el principal problema de GraphQL sea el overfetching
Para mí, la verdadera ventaja es que (a) impone contratos estrictos basados en tipos, y (b) la evolución del esquema es mucho más fácil
Gracias al sistema de tipos, las entradas y salidas siempre siguen una forma definida, y al usar tipos escalares personalizados (por ejemplo, número de teléfono, correo electrónico, etc.) se pueden reducir mucho los bugs y los problemas de seguridad
Además, como agregar campos nuevos o deprecar campos existentes está estandarizado, tanto el servidor como el cliente tienen menos carga cognitiva
Uso GraphQL por la composición y evolución de APIs. Sobre todo en sistemas grandes con estructura M:N, el flujo de “el cliente describe lo que necesita → el servidor lo compone → los servicios de dominio lo resuelven” es mucho más fácil de mantener a largo plazo
Si se combina con buena observability, se vuelve una base muy poderosa para el acceso a datos
Otra ventaja es que facilita la reutilización de resolvers y la federation. En REST eso es bastante engorroso
La evolución del esquema también la maneja bien Protobuf
La verdadera ventaja de GraphQL es que permite componer los datos de la UI en pequeñas piezas
Como en este video, si aprovechas fragment colocation, puedes modificar componentes hijos sin afectar otras partes
Como la query se genera automáticamente a partir de fragments, también se reduce el riesgo de romper otros componentes al eliminar campos
Si la escala es pequeña o la velocidad de desarrollo no es tan importante, GraphQL puede parecer una sobreinversión
Colocation es un concepto realmente revolucionario, pero Apollo casi no lo mencionó
La documentación de Relay sigue siendo insuficiente, pero el concepto de Entrypoint es excelente
Pero la implementación de graphql-codegen tiene poca compatibilidad entre plugins, así que tuvimos que crear nuestro propio plugin
Falta consistencia en todo el ecosistema
Decir que el overfetching es el problema central de GraphQL es una exageración
Pienso que GraphQL es una herramienta para tratar a nivel cliente la discordancia de impedancia que los ORM resuelven
Usarlo sin tooling basado en compilador como Relay es un antipatrón
Hoy en día la IA genera automáticamente la capa de datos, así que parece que la necesidad de GraphQL está disminuyendo
Tiene una experiencia de desarrollo (DevEx) excelente, incluso autogenera cosas cuando seleccionas campos que no existen
La lentitud de la web moderna se debe en su mayoría al envío excesivo de datos. De hecho, muchas apps funcionan con una eficiencia inferior al 0.5%
He usado GraphQL desde 2016
En esencia, GraphQL es una especificación de RPC. Se implementa como un mapa del servidor de “Action(Args) → ResultType”
En lugar de varios endpoints como en REST, GraphQL funciona a través de un único endpoint
/queryusando un mapa de resolversAl final, es una estructura donde entradas y salidas están definidas por tipos, como OpenAPI o gRPC
Apollo mejoró un poco al agregar fragment masking, pero sigue siendo importante pensar con Relay como centro
y el backend la transforma en una única query SQL para procesarla
Los resolvers deberían usarse solo como excepción para datos que no pueden obtenerse directamente desde la base de datos
En el pasado, cuando lideraba un equipo, el FE quería GraphQL y lo adoptamos
Como resultado, cada página traía todos los datos con una query enorme, y al modificar algo se reenviaba todo el JSON blob
La app funcionaba, pero al final la empresa pivoteó y ese código desapareció
En la práctica, muchos proyectos con GraphQL parecen terminar así, como implementaciones meramente formales
El flujo de autenticación (auth) en GraphQL es uno de los retos más grandes
Como los resolvers se llaman desde contextos diversos, hay que considerar todos los casos
La complejidad y el costo mental son tan altos que al final terminas bloqueando campos
Incluso hice yo mismo graphql-autharoo, pero no fue suficiente
La mayoría de las funciones pueden implementarse de forma más simple sin GraphQL
Hay que agregar permisos finos a cada recurso de GraphQL, así que las queries no funcionan hasta que se actualiza todo el recurso
La carga es tan grande que uno termina diciendo: “mejor rehagámoslo en REST”
Creo que es mejor usar un framework de servidor bien resuelto que componer todo manualmente
GraphQL se ve bien a primera vista, pero en la práctica es una tecnología que se vuelve difícil de mantener con el tiempo
Como tantas otras tecnologías, deja la lección de que una rueda sigue siendo una rueda
La ventaja de GraphQL es que basta con agregar campos al esquema para que todos los clientes puedan consultarlos de inmediato
Desaparecen las peticiones del FE de “agrégame este campo también”, y la colaboración se simplifica
Además, es fácil crear snapshots del esquema para detectar cambios en pruebas de integración
Me pareció más consistente que REST, aunque eso es una experiencia personal
Como puedes encadenar requests de A hasta E, aumentan los problemas de rendimiento y el acoplamiento entre frontend y estructura de datos
React también toma ahora como base el SSR orientado a frameworks y los server components
Al final, todo apunta a que TypeScript está unificando cliente y servidor
Me pregunto cómo evita GraphQL los problemas de carga en la base de datos o queries ineficientes
¿No podría una query maliciosa hacer explotar el estado interno?
REST es demasiado aburrido, así que estoy probando GraphQL
Me gusta que servidor y cliente puedan ponerse de acuerdo en requests y responses en tiempo de compilación
Ojalá los blogs no se limitaran a decir “esto está mal”, sino que también propusieran tecnologías alternativas
Ambas tecnologías resuelven muy bien el problema del contrato cliente-servidor