Desarrollo11 de julio de 2026

Personalización del esquema GraphQL de Gatsby para principiantes

Gatsby tiene una gran diferencia respecto a otros frameworks: incorpora una capa de datos GraphQL. Esa capa abre muchas posibilidades y es una pieza clave de su amplio ecosistema de plugins. Con GraphQL puedes obtener datos de un CMS, consultar imágenes o consultar contenido en markdown gracias a una gran variedad de plugins.

Todo esto es posible porque esos plugins obtienen los datos de sus fuentes y los transforman en nodos GraphQL durante el build. En la mayoría de los casos es más que suficiente, y ni siquiera necesitas dominar GraphQL para usar Gatsby y construir cosas interesantes.

Pero hoy quiero hablar de la Schema Customization API de Gatsby, porque en ciertos casos puede mejorar muchísimo la calidad de un proyecto.

¿Qué es la Schema Customization API de Gatsby?

Esta API permite interactuar con la capa de datos GraphQL y personalizarla como quieras. Sirve para ampliar los tipos GraphQL existentes o crear otros completamente nuevos.

Casos de uso

Si estás empezando, seguramente te resulten útiles estos escenarios habituales:

  • Sustituir datos en un campo GraphQL existente
  • Añadir un campo nuevo a un tipo GraphQL existente y rellenarlo con datos
  • Definir relaciones entre tipos GraphQL

Sustituir datos en un campo GraphQL existente

Esta técnica es muy útil cuando quieres definir un valor por defecto para un campo existente. Por ejemplo, tienes un blog con artículos en markdown y algunos llevan el flag draft: true, pero otros no. Para filtrar mejor, quieres asegurarte de que todos los posts tengan en GraphQL un campo draft con valor false o true.

Hay dos formas de conseguirlo. La primera es usar la API onCreateNode (documentación) que ofrece Gatsby. Solo tienes que ir a gatsby-node.js y añadir estas líneas.


exports.onCreateNode = ({ node, actions }) => {
const { createNodeField } = actions;
if (node.frontmatter) {
createNodeField({
node,
name: 'isDraft',
value: node.frontmatter.isDraft || false,
});
}
};

Este código se ejecuta cada vez que se crea un nodo, así que conviene filtrar los nodos por ciertos parámetros para añadir el campo solo a los que corresponda. Es una solución rápida, pero algo tosca. Como ves, el campo original isDraft del frontmatter de markdown se queda como estaba y creamos uno nuevo en ese nodo, dentro de fields.

Para un mejor rendimiento, podemos usar un enfoque más granular: sobrescribir el campo original con un resolver personalizado. Este método requiere algo más de conocimiento. Necesitaremos saber el tipo GraphQL exacto que queremos modificar. Para averiguar su nombre, podemos arrancar Gatsby con un flag especial: GATSBY_GRAPHQL_IDE=playground npm start. Así veremos GraphQL Playground en lugar del IDE GraphiQL en http://localhost/__graphql y podremos obtener ahí la información que necesitamos.

Abre el panel Schema y busca el tipo con Ctrl+F. Una vez encontrado, vemos que el tipo que buscamos es MdxFrontmatter y que el campo isDraft es de tipo Boolean. Así que, con ayuda de la API createResolvers (documentación) declarada en gatsby-node.js, podemos definir un valor por defecto para el campo.


exports.createResolvers = ({ createResolvers }) => {
createResolvers({
MdxFrontmatter: {
isDraft: {
type: 'Boolean',
resolve: ({ isDraft }) => isDraft || false,
},
},
});
};

Como ves, en el campo isDraft ya no hay valores null: solo false o true.

Añadir un campo nuevo a un tipo GraphQL existente y rellenarlo con datos

Acabamos de ver cómo modificar datos existentes; ahora vamos un paso más allá y añadimos un campo completamente nuevo. Veamos un ejemplo: imagina una web con casos de estudio de proyectos open source guardados en markdown, en la que quieres obtener durante el build el número de estrellas de GitHub de cada uno. Es una tarea perfecta para la personalización del esquema GraphQL de Gatsby.

Para cada caso de estudio queremos declarar un campo githubStars e indicarle a Gatsby que obtenga los datos de la API de GitHub. Ya hemos usado la función createResolvers para modificar un campo, pero también sirve para añadir uno nuevo.

Desde GraphQL Playground podemos obtener el tipo que se usa para los archivos markdown, que será Mdx, y añadir el campo nuevo de esta forma.


exports.createResolvers = ({ createResolvers }) => {
createResolvers({
Mdx: {
githubStars: {
type: 'String',
resolve: async ({ frontmatter, fileAbsolutePath }) => {
const { name, githubUsername, githubRepoName, isOpenSource } = frontmatter;
if (
fileAbsolutePath.includes('/case-studies/') &&
isOpenSource &&
githubUsername &&
githubRepoName
) {
try {
const response = await fetch(
`https://api.github.com/repos/${githubUsername}/${githubRepoName}`
);
const { stargazers_count } = await response.json();
return new Intl.NumberFormat('en-US').format(stargazers_count);
} catch (e) {
throw new Error(`Failed to fetch GitHub stars for case study "${name}"`);
}
}
return null;
},
},
},
});
};

La función resolve recibe todos los datos del nodo, así que es fácil filtrar los archivos mdx según ciertas reglas, por ejemplo, la carpeta en la que están. El resolver puede ser una función asíncrona, así que también puedes hacer llamadas externas desde ahí sin problema.

Definir relaciones entre tipos GraphQL

Otro caso de uso habitual. Tienes un blog en markdown y una lista de autores en JSON. Quieres obtener todos los datos desde la capa GraphQL, de modo que el autor aparezca anidado dentro de los datos del post. Puedes conseguirlo con el hook createSchemaCustomization de gatsby-node.js usando la API createTypes (documentación).

La estructura del objeto JSON de autor podría ser así:


/// content/posts/post-authors.json
[
{
"name": "Jane Doe",
"photo": "../../src/images/post-authors/jane-doe.jpg",
"description": "Software engineer with 10+ years of web development experience. Currently focused on React, Next.js, Gatsby."
},
... more authors
]

Y el contenido del post podría ser algo así:


// content/posts/example.md
---
title: 'Taking automated web page screenshots with Puppeteer and Sharp'
summary: A step-by-step tutorial on how to create perfect high-resolution web page screenshots automatically. No fuss, it just works.
author: Jane Doe
cover: cover.jpg
category: Development
---
... Blog post content

Como ves, tenemos el nombre del autor en el frontmatter del post y ese mismo nombre en authors.json. Ahora el objetivo es que el autor sea accesible desde GraphQL como objeto anidado al obtener los datos del post.

Nota: para los posts del blog usamos gatsby-plugin-mdx, y para cargar los datos JSON en GraphQL, gatsby-transformer-json.

Esta es la configuración de gatsby-config.js que hace posible esa carga de datos:


{
resolve: 'gatsby-source-filesystem',
options: {
name: 'posts',
path: `${__dirname}/content/posts`,
},
},
{
resolve: 'gatsby-source-filesystem',
options: {
name: 'post-authors',
path: `${__dirname}/content/posts/post-authors.json`,
},
},

Seguimos la misma estrategia que antes: abrimos GraphQL Playground. Ya conocemos el tipo GraphQL de los archivos markdown, pero necesitamos encontrar el tipo de los nodos basados en JSON. En nuestro caso será PostAuthorsJson .

Con esa información, podemos añadir createSchemaCustomization a gatsby-node.js y usar una función llamada createTypes. Esta técnica permite modificar el esquema GraphQL.

Nota: si quieres sobrescribir por completo un tipo GraphQL existente, usa la directiva @dontInfer junto a la definición del tipo (documentación).

Hay varias opciones para definir manualmente relaciones anidadas. Pero la más sencilla es usar la directiva integrada @link. Piensa en ella como un helper que mapea dos tipos GraphQL a partir de las relaciones de clave foránea que le indiques.

Vamos a probarlo. Añade este código a gatsby-node.js y mira el resultado.


exports.createSchemaCustomization = ({ actions }) => {
const { createTypes } = actions;
createTypes(`
type Mdx implements Node {
author: PostAuthorsJson @link(by: "name", from: "frontmatter.author")
}
`);
};

Ahora los autores están vinculados a los nodos markdown. Así puedes obtener datos anidados e incluso filtrar los resultados por la información del autor.

Resumen

Ya sabes cómo modificar el esquema GraphQL de Gatsby. Espero que te resulte útil en tu proyecto.

Cuéntanos tu caso

Escríbenos