Gatsby 5: Cómo consultar datos de múltiples fuentes con GraphQL
Introducción
Hace un tiempo que migré mi blog de WordPress a Gatsby.
Cuándo comencé el proceso de migración, opté por utilizar JavaScript y el plugin
gatsby-transformer-javascript-frontmatter
para generar las páginas de mi blog.
Hace poco, decidí darle una oportunidad a MDX. MDX me proporcionaba casi las mismas características que podía obtener con JavaScript, además de la posibilidad de tener entradas con una sintaxis mucho más limpia y clara.
El principal reto ahora era poder consultar datos de ambas fuentes, JavaScript frontmatter
y MDX frontmatter
,
para proporcionar una experiencia de desarrollo consistente y limpia.
Afortunadamente, ambos plugins utilizaban una estructura de frontmatter
similar, lo que hizo la tarea sencilla.
Este es mi caso de uso particular y mi principal motivación. Sin embargo, estoy seguro de que hay muchos otros casos de uso que pueden necesitar este requisito. En este artículo, compartiré mi viaje y te guiaré a través de la personalización del esquema GraphQL de Gatsby para consultar datos de múltiples fuentes.
Personalizando el esquema GraphQL
El esquema GraphQL consumido por Gatsby puede personalizarse aprovechando el callback
createSchemaCustomization
en el archivo gatsby-node.js
.
Aquí tienes una estructura básica de la función createSchemaCustomization
:
exports.createSchemaCustomization = ({actions}) => {
const {createTypes} = actions;
const typeDefs = `
# type definitions
`;
createTypes(typeDefs);
};
En primer lugar, creamos una interfaz de GraphQL que implementarán tanto los nodos JavaScript como los nodos MDX frontmatter
.
Aquí tienes un fragmento de la definición de la interfaz que forma parte de la constante typeDefs
de la estructura anterior:
interface BlogPost implements Node {
id: ID!
frontmatter: Frontmatter!
fields: FrontmatterDerivedFields!
allFrontmatter: JSON!
allFields: JSON!
}
La interfaz BlogPost
extiende la interfaz base Node
, que es común a todos los nodos de Gatsby.
A continuación, definimos los campos que son comunes tanto a los nodos JavaScript como a los nodos MDX frontmatter
.
En mi caso, el campo frontmatter
es el que ambos plugins oficiales de frontmatter
proporcionan.
Y el campo fields
, que es uno que genero durante el callback
onCreateNode
para ambos tipos de nodos.
A continuación, definimos los tipos Frontmatter
y FrontmatterDerivedFields
:
type Frontmatter {
slug: String!
langKey: String!
author: String!
title: String!
created: String!
lastModified: String!
categories: [String!]!
tags: [String!]!
description: String!
image: String!
readingTime: String!
comments: File @fileByRelativePath
pageQuery: String
}
type FrontmatterDerivedFields {
type: String!
filePath: String!
createdYear: Int!
createdMonth: String!
createdDay: String!
createdYearMonth: Date! @dateformat
createdDateShort: Date! @dateformat
lastModifiedDateShort: Date! @dateformat
}
Aunque no es estrictamente necesario (ya que Gatsby puede inferir los tipos),
estas definiciones de tipo aseguran que cada nodo frontmatter
debe contener todos los campos especificados.
Sin embargo, si no añadimos estos tipos, al menos un nodo de cada tipo frontmatter
debe contener todos los campos.
Por último, definimos los tipos Mdx
y JavascriptFrontmatter
, ambos implementando la interfaz BlogPost
:
type Mdx implements Node & BlogPost {
id: ID!
frontmatter: Frontmatter!
fields: FrontmatterDerivedFields!
allFrontmatter: JSON! @proxy(from: "frontmatter")
allFields: JSON! @proxy(from: "fields")
}
type JavascriptFrontmatter implements Node & BlogPost {
id: ID!
frontmatter: Frontmatter!
fields: FrontmatterDerivedFields!
allFrontmatter: JSON! @proxy(from: "frontmatter")
allFields: JSON! @proxy(from: "fields")
}
Este es todo el contenido que debemos de añadir a la constante typeDefs
.
Con esto, hemos definido el esquema GraphQL que será consumido por Gatsby y que nos permitirá consultar datos de
los frontmatters
de MDX y JavaScript.
Observa la directiva @proxy
en los campos allFrontmatter
y allFields
.
Estos son campos artificiales que replican los proporcionados en los campos frontmatter
y fields
.
Utilizo esto como un hack para poder consultar campos frontmatter
sin necesidad de especificarlos en la consulta GraphQL.
Veamos ahora cómo podemos consultar datos de ambas fuentes.
Consultando datos de múltiples fuentes
Con la interfaz BlogPost
definida, podemos consultar datos de ambos fuentes de forma eficiente.
Aquí tienes un ejemplo de consulta que recupera los campos title
y slug
de ambas fuentes:
query MyQuery {
allBlogPost {
edges {
node {
frontmatter {
slug
title
}
}
}
}
}
En lugar de ejecutar dos consultas separadas y fusionar los resultados en el cliente, este enfoque nos permite ejecutar una única consulta que recupera los datos de ambas fuentes. Además, también podremos ordenar los resultados fusionados por cualquier campo:
query MyQuery {
allBlogPost(sort: {frontmatter: {created: ASC}}) {
# ...
}
}
Conclusión
En este artículo, he demostrado cómo personalizar el esquema GraphQL de Gatsby para consultar datos de múltiples fuentes.
Más concretamente, el campo frontmatter
que es proporcionado por los plugins JavaScript y MDX frontmatter
.
Este sencillo a la vez que efectivo proceso asegura una experiencia de desarrollo consistente al trabajar con datos de fuentes diversas. Espero que este artículo te resulte útil para abordar tus casos de uso particulares y agilizar tu flujo de trabajo de desarrollo.