API Query Language

GraphQL

GraphQL permite que los clientes soliciten exactamente los datos que necesitan en una sola petición. Un esquema tipado describe la API y los resolvers obtienen los datos que hay detrás.

intermediate14 min readUpdated 15 sept 2026
query.graphql
graphql
// query.graphql
query UserWithPosts($id: ID!) {
  user(id: $id) {
    name
    posts(first: 3) {
      title
    }
  }
}
Creado por
Facebook, 2012
Lanzado
2015, open source
Esquema
Un contrato tipado
Operaciones
Query, mutation, subscription
Transporte
Usualmente HTTP, un solo endpoint
Servidor
Resolvers detrás del esquema

Por que importa

Por qué los equipos adoptan GraphQL

Pide lo que necesites

Los clientes seleccionan los campos exactos que utilizan, por lo que las respuestas no sufren de over-fetching ni under-fetching.

Una petición, muchos recursos

Una sola query puede recorrer relaciones que, de otro modo, requerirían varios viajes de ida y vuelta en REST.

Un contrato tipado

El esquema es autodocumentado y permite el autocompletado, la validación y la generación de código.

La imagen completa

Las tres ideas detrás de GraphQL

Un esquema tipado describe los datos, una query selecciona exactamente lo que se necesita y los resolvers suministran cada campo.

El esquema

Contrato

Tipos, campos y operaciones que describen exactamente qué puede devolver la API.

La query

Selección

Un documento del cliente que selecciona campos y pasa argumentos y variables.

Los resolvers

Resolución

Funciones que obtienen los datos de cada campo, a menudo desde bases de datos o servicios.

GraphQL de un vistazo

El núcleo de GraphQL

Tipos y esquema

Tipos de objeto, scalars, enums, interfaces y unions.

Queries

Lectura de datos seleccionando campos desde el tipo de query raíz.

Mutations

Escritura de datos, con una entrada explícita y una forma de retorno definida.

Subscriptions

Transmisión de actualizaciones en tiempo real a través de una conexión persistente.

Variables y fragments

Reutilización de selecciones de campos y paso de argumentos tipados.

Clientes

Apollo, urql y Relay gestionan el caching y las peticiones.

Una breve historia

De una API interna de Facebook a un estándar de la industria

  1. 2012

    Creado en Facebook

    Facebook crea GraphQL para potenciar sus aplicaciones móviles con una obtención de datos eficiente.

    12
  2. 2015

    Lanzamiento open source

    La especificación y la implementación de referencia se publican abiertamente.

    15
  3. 2018

    Formación de la fundación

    Se crea la GraphQL Foundation para gestionar la especificación.

    18
  4. 2020

    Adopción masiva

    Apollo, urql y Relay maduran, y GraphQL se vuelve común en las APIs de producto.

    20
  5. Hoy

    Una herramienta estándar

    Ampliamente utilizado para APIs públicas, servicios internos y grafos federados.

    Hoy

La guia completa

GraphQL: Todo lo que necesitas saber

¿Qué es GraphQL?

GraphQL es un lenguaje de consultas y un runtime para APIs. En lugar de exponer múltiples endpoints fijos, un servidor GraphQL expone un único schema tipado, y los clientes envían consultas que seleccionan exactamente los campos que necesitan. El servidor resuelve cada campo y devuelve una respuesta con la misma estructura que la solicitud.

Facebook lo creó en 2012 para resolver un problema en dispositivos móviles: los endpoints de REST devolvían demasiados o muy pocos datos, y obtener toda la información relacionada para una pantalla requería demasiados viajes de ida y vuelta (round trips). GraphQL solucionó ambos problemas permitiendo que el cliente describiera sus requisitos de datos en un solo documento.

El esquema

El esquema es el contrato. Define los tipos y las operaciones disponibles.

# schema.graphql
type User {
  id: ID!
  name: String!
  email: String
  posts(first: Int = 10): [Post!]!
}

type Post {
  id: ID!
  title: String!
  body: String!
  author: User!
}

type Query {
  user(id: ID!): User
  posts(limit: Int): [Post!]!
}

type Mutation {
  createPost(input: CreatePostInput!): Post!
}

El símbolo ! marca un campo como no nulo. Los tipos se componen en un grafo, razón por la cual una sola consulta puede navegar desde un usuario hacia sus posts y volver a los autores. El esquema es introspectable, por lo que las herramientas pueden generar documentación, tipos y autocompletado automáticamente.

Queries

Una query selecciona campos del tipo de query raíz, utilizando argumentos y variables.

# posts.graphql
query RecentPosts($limit: Int!) {
  posts(limit: $limit) {
    id
    title
    author {
      name
    }
  }
}

La respuesta refleja exactamente la selección: sin campos adicionales ni omisiones. Las variables permiten que las queries sean reutilizables y dejan que el servidor valide los tipos de los argumentos. Los fragments extraen selecciones repetidas para su reutilización.

# fragment.graphql
fragment PostCard on Post {
  id
  title
  author { name }
}

query Feed {
  posts { ...PostCard }
}

Mutations y subscriptions

Una mutation modifica datos y devuelve una estructura definida, que a menudo incluye el objeto actualizado para que el cliente pueda actualizar su caché.

# create.graphql
mutation CreatePost($input: CreatePostInput!) {
  createPost(input: $input) {
    id
    title
  }
}

Una subscription transmite actualizaciones en tiempo real a través de una conexión persistente, como mensajes nuevos o notificaciones en vivo. Utilízala cuando el servidor deba enviar datos al cliente; para actualizaciones ocasionales, el polling o un refetch es más sencillo.

Resolvers

Los resolvers son el punto de encuentro entre el esquema y tus datos. Cada campo tiene un resolver que devuelve su valor.

// resolvers.js
const resolvers = {
  Query: {
    user: (_parent, { id }, { db }) => db.users.findById(id),
    posts: (_parent, { limit = 10 }, { db }) => db.posts.findMany({ limit }),
  },
  User: {
    posts: (user, { first }, { db }) =>
      db.posts.findMany({ where: { authorId: user.id }, limit: first }),
  },
  Mutation: {
    createPost: (_parent, { input }, { db }) => db.posts.create(input),
  },
};

El objeto context transporta recursos compartidos, como la base de datos y el usuario autenticado. Los resolvers deben ser pequeños, y las comprobaciones de autorización deben realizarse aquí o en la capa de servicio que invoquen — nunca en el cliente.

El problema N+1

La trampa de rendimiento más común en GraphQL son las consultas N+1. Si una consulta devuelve diez posts y el resolver del autor de cada post hace una petición a la base de datos, terminarás ejecutando once consultas.

DataLoader soluciona esto mediante el agrupamiento (batching) y el almacenamiento en caché de las llamadas dentro de una misma solicitud.

// loaders.js
import DataLoader from "dataloader";

function createUserLoader(db) {
  return new DataLoader(async (ids) => {
    const users = await db.users.findByIds(ids);
    return ids.map((id) => users.find((u) => u.id === id));
  });
}

Luego, el resolver del autor llama a loaders.user.load(post.authorId), y DataLoader agrupa todas las cargas del tick en una sola consulta. Esta es la optimización más importante que puedes implementar en un servidor GraphQL.

Clientes y almacenamiento en caché

Las librerías de cliente como Apollo Client y urql proporcionan almacenamiento en caché, normalización, gestión de estados de carga y error, e integración con frameworks de UI. Una caché normalizada almacena las entidades por tipo e id, de modo que una mutation que devuelve un post actualizado actualiza automáticamente cada query que haga referencia a él.

Debido a que GraphQL utiliza normalmente un único endpoint POST, el almacenamiento en caché de HTTP es menos efectivo que con REST. Los clientes compensan esto con cachés normalizadas, y los servidores utilizan persisted queries y almacenamiento en caché de respuestas. Diseña tus mutations para que devuelvan los objetos modificados y así la caché del cliente pueda mantenerse consistente.

¿GraphQL o REST?

GraphQL destaca cuando:

  • Los clientes necesitan campos diferentes para distintas pantallas.
  • Una pantalla requiere datos de muchos recursos relacionados.
  • Buscas una API única, tipada y autodocumentada.

REST es más sencillo cuando:

  • Los recursos se mapean limpiamente a endpoints.
  • El almacenamiento en caché de HTTP y los códigos de estado son fundamentales.
  • La API es pequeña y estable.

Muchos equipos utilizan ambos, empleando GraphQL para la API del producto y REST para webhooks, subida de archivos y endpoints públicos sencillos.

Mejores prácticas

  • Diseña el esquema basándote en las necesidades del cliente, no en las tablas de la base de datos.
  • Usa tipos no nulos de forma deliberada y gestiona las versiones del esquema mediante deprecaciones.
  • Mantén los resolvers ligeros y desplaza la lógica hacia los servicios.
  • Soluciona el problema N+1 con DataLoader desde el principio.
  • Añade límites de profundidad y complejidad a las consultas para evitar abusos.
  • Devuelve los objetos modificados en las mutations para mantener la consistencia de la caché.
  • Usa persisted queries en producción para reducir el tamaño del payload.

Errores comunes

  • Exponer el esquema de la base de datos directamente como el esquema de GraphQL.
  • Ignorar el problema N+1 hasta que el rendimiento colapse.
  • Solicitar todos los datos en cada consulta y perder el beneficio principal.
  • Confiar en la autorización proporcionada por el cliente o en los permisos a nivel de campo.
  • Construir consultas profundamente anidadas sin un límite de profundidad.
  • Asumir que el almacenamiento en caché de HTTP funciona igual que con REST.

Próximos pasos

GraphQL es una forma potente de diseñar APIs centradas en el cliente. Impleméntalo sobre el protocolo HTTP, construye el servidor en Node.js y consúmelo desde React utilizando una librería de cliente. Después, modela una pantalla que conozcas bien como un esquema y una consulta, y observa qué tan naturalmente se mapean los requerimientos de datos.

Solicitud de datos

GraphQL devuelve exactamente los campos seleccionados. Los endpoints de REST a menudo devuelven mucho más de lo que el cliente necesita, desperdiciando ancho de banda y tiempo de procesamiento.

Preferir
query {
  user(id: "1") {
    name
    avatar
  }
}
// only name and avatar
// cross the wire
Evitar
// GET /users/1 returns
// the entire user record,
// including fields the
// client never displays

Obtención de datos relacionados

Una sola query de GraphQL puede recorrer relaciones, evitando los múltiples viajes de ida y vuelta que haría un cliente REST.

Preferir
query {
  user(id: "1") {
    name
    posts(first: 3) {
      title
      comments { text }
    }
  }
}
Evitar
# three requests:
# /users/1
# /users/1/posts
# /posts/:id/comments

Preguntas frecuentes

Preguntas frecuentes

Keep learning

Related topics from the roadmap.

$ comienza a aprender

Listo para aprender GraphQL?

Nuestro tutorial interactivo te guia a traves de GraphQL paso a paso — con quizzes y codigo real que puedes ejecutar en el navegador.