Elegir el estilo arquitectónico correcto para tus APIs es una de las decisiones más influyentes en el rendimiento y mantenimiento a largo plazo de cualquier sistema web. Durante años, API REST ha sido el estándar incuestionable, pero GraphQL ha ganado un terreno masivo al cambiar el equilibrio de poder en favor de los clientes de frontend.
El Problema de REST: Over-fetching and Under-fetching
En una API REST clásica, cada punto de conexión (endpoint) devuelve una estructura de datos fija. Esto genera dos ineficiencias de red críticas en aplicaciones móviles y web complejas:
- Over-fetching: El servidor devuelve campos innecesarios. Por ejemplo, para mostrar una lista de nombres de usuarios en un desplegable, REST descarga perfiles enteros que incluyen biografías, fechas de creación, roles y direcciones, desperdiciando ancho de banda.
- Under-fetching: Un solo endpoint no contiene suficiente información. Para renderizar una pantalla que muestra un usuario, sus últimos 5 proyectos y sus facturas asociadas, el frontend debe realizar tres peticiones consecutivas: /users/1, /users/1/projects y /users/1/invoices. Esto multiplica la latencia de red (Round Trip Time).
GraphQL: Flexibilidad Absoluta para el Cliente
GraphQL resuelve estos problemas exponiendo un único endpoint inteligente (`/graphql`) que responde a consultas personalizadas estructuradas. El cliente declara exactamente qué campos y relaciones necesita, y el motor de GraphQL consolida los datos y devuelve una respuesta con la estructura exactas solicitada.
// Resolver de GraphQL en NestJS utilizando TypeGraphQL/Apollo
import { Resolver, Query, Args } from '@nestjs/graphql';
import { Project } from './models/project.model';
import { ProjectService } from './project.service';
@Resolver(() => Project)
export class ProjectResolver {
constructor(private readonly projectService: ProjectService) {}
@Query(() => [Project])
async projectsByDeveloper(@Args('devId') devId: string) {
// El motor de GraphQL filtrará automáticamente los campos solicitados por el cliente
return this.projectService.findByDeveloper(devId);
}
} El talón de Aquiles de GraphQL: El problema N+1 de SQL
Aunque GraphQL es ideal para el frontend, traslada la carga de complejidad al servidor. El problema más común en producción es el problema de consultas N+1. Si solicitas una lista de 50 proyectos y, para cada proyecto, pides los detalles del cliente propietario, un resolver ingenuo de GraphQL ejecutará una consulta SQL para traer los proyectos, y luego 50 consultas individuales en bucle para traer a cada cliente.
Para evitar que tu base de datos colapse en producción, es obligatorio implementar mecanismos de procesamiento por lotes como DataLoader. DataLoader agrupa las 50 peticiones de clientes individuales en una única consulta SQL optimizada: `SELECT * FROM clients WHERE id IN (...)`.
""REST es predecible en el servidor y complejo en el cliente. GraphQL es simple en el cliente y exigente en el servidor.""
¿Cuándo elegir cuál? Reglas Prácticas
- Elige REST cuando construyas servicios públicos que requieran un almacenamiento en caché en la red de borde (HTTP CDN Caching) sencillo, cuando el ancho de banda no sea crítico o cuando la API sea simple.
- Elige GraphQL cuando construyas aplicaciones móviles de alto rendimiento, paneles de control con datos altamente interconectados (relaciones de muchos a muchos) y cuando tengas múltiples equipos de frontend consumiendo la misma base de datos de manera ágil.