El problema de REST
En REST cada recurso es una URL. Eso lleva a dos molestias frecuentes:
- Over-fetching:
GET /usuarios/1te devuelve todos los campos aunque solo necesites el nombre. - Under-fetching: para pintar una pantalla a veces hacen falta varias
llamadas (
/usuarios/1, luego/usuarios/1/pedidos...), el clásico problema "N+1 peticiones".
GraphQL
GraphQL ofrece un único endpoint (/graphql) y un esquema tipado
que describe qué datos existen. El cliente pide exactamente los campos que
necesita, ni más ni menos, en una sola petición.
type Usuario {
id: ID!
nombre: String!
email: String!
}
type Query {
usuario(id: ID!): Usuario
}
Una query (lectura) declara la forma exacta de lo que quiere:
query {
usuario(id: "1") {
nombre # pido solo nombre y email,
email # no el resto de campos
}
}
Y una mutation (escritura) crea o modifica datos:
mutation {
crearUsuario(nombre: "Ana") {
id
}
}
Resolvers
Detrás de cada campo del esquema hay una función llamada resolver, que resuelve (calcula o busca) el valor de ese campo. Un resolver no es magia: es solo una función. Recibe argumentos estándar:
// resolver(padre, args, contexto, info)
const resolvers = {
Query: {
usuario(_padre, args, contexto) {
return contexto.usuarios.find((u) => u.id === args.id);
},
},
};
- padre: el resultado del campo de nivel superior (raíz: suele ignorarse).
- args: los argumentos de la query (
{ id: "1" }). - contexto: datos compartidos por petición (BD, usuario autenticado...).
El motor de GraphQL recorre la query, llama al resolver de cada campo pedido y ensambla la respuesta con la forma exacta solicitada.