Utilisation avancée de GraphQL dans les sites Web Gatsby

Publié: 2022-03-10
Résumé rapide ↬ Dans cet article, Aleem Isiaka explique ce que sont les constructions de requête GraphQL et comment elles peuvent être utilisées pour interagir avec la couche d'accès aux données d'un site Web Gatsby. Jetons un coup d'œil à certains des cas d'utilisation avancés de GraphQL dans un site Web Gatsby en utilisant des données correspondantes provenant de différentes sources.

Avant la sortie de GraphQL en 2015, le transfert d'état représentatif (REST) ​​était le principal moyen d'interface avec une API. L'introduction de GraphQL a donc été un changement majeur dans le développement logiciel.

En tant que générateur de site statique moderne, Gatsby exploite GraphQL pour fournir une méthodologie concise pour importer et manipuler des données dans le cadre. Dans cet article, nous examinerons de plus près GraphQL et comment nous pouvons l'intégrer dans un site Web Gatsby en créant et en mettant en œuvre un sourçage et une transformation avancés des données dans Gatsby. Le résultat est un blog d'éditeur qui pourrait être utilisé par n'importe quelle maison d'édition pour partager le contenu de leurs auteurs.

Qu'est-ce que GraphQL ?

Sous le nom de QL , GraphQL est un langage de requête combiné à un ensemble d'outils créés pour offrir flexibilité et efficacité dans la manière dont nous extrayons les données d'une source. Avec GraphQL, un client/consommateur peut demander exactement les données dont il a besoin. Le serveur/fournisseur répond avec une signature de réponse JSON correspondant aux exigences spécifiées dans la requête. Il nous permet d'exprimer nos besoins en données de manière déclarative.

Pourquoi utiliser GraphQL ?

En tant que générateur de site statique, Gatsby stocke des fichiers statiques, ce qui rend l'interrogation des données presque impossible. Il y a souvent des composants de page qui doivent être dynamiques comme la page de publication de blog unique, donc le besoin d'extraire des données d'une source et de les transformer au format nécessaire se poserait, tout comme avoir des articles de blog stockés dans des fichiers de démarquage. Certains plugins fournissent des données provenant de diverses sources, ce qui vous laisse interroger et transformer les données requises à partir d'une source.

Selon une liste sur gatsby.org, GraphQL est utile dans Gatsby pour :

  • Éliminer le passe-partout
  • Poussez les complexités du frontend dans les requêtes
  • Fournir une solution parfaite pour les données toujours complexes d'une application moderne
  • Enfin, pour supprimer le gonflement du code, améliorant ainsi les performances.

Concepts GraphQL

Gatsby maintient les mêmes idées de GraphQL largement utilisées ; certains de ces concepts sont :

Langage de définition de schéma

GraphQL SDL est un système de type intégré à GraphQL, et vous pouvez l'utiliser pour créer de nouveaux types pour vos données.

Nous pouvons déclarer un type pour un pays, et ses attributs pourraient inclure un nom, un continent, une population, un pib et un nombre d'états.

Comme exemple ci-dessous, nous avons créé un nouveau type avec le nom de Aleem . Il a des hobbies -temps qui sont un tableau de chaînes et ne sont pas obligatoires, mais le pays, l'état civil et les messages sont nécessaires en raison du ! ils incluent, publie également des références à un autre type, Post .

 type Author { name: String!, hobbies: [String] country: String! married: Boolean! posts: [Post!] } type Post { title: String! body: String! } type Query { author: Author } schema { query: Query }

Requêtes

Nous pouvons utiliser des requêtes pour extraire des données d'une source GraphQL.

Considérant un ensemble de données comme ci-dessous

 { data: { author: [ { hobbies: ["travelling", "reading"], married: false, country: "Nigeria", name: "Aleem Isiaka", posts: [ { title: "Learn more about how to improve your Gatsby website", }, { title: "The ultimate guide to GatsbyJS", }, { title: "How to start a blog with only GatsbyJS", }, ], }, ], }, };

Nous pouvons avoir une requête pour récupérer le pays et les publications à partir des données :

 query { authors { country, posts { title } } }

La réponse que nous obtiendrons devrait contenir les données JSON des articles de blog avec juste le titre et rien de plus :

 [ { country: “Nigeria”, posts: [{...}, {...}, {...}] }, { country: “Tunisia”, posts: [] }, { title: “Ghana”, posts: []}, ]

Nous pouvons également utiliser des arguments comme conditions pour une requête :

 query { authors (country: “Nigeria”) { country, posts { title } } }

Qui devrait revenir

 [ { country: “Nigeria”, posts: [{...}, {...}, {...}] } ]

Les champs imbriqués peuvent également être interrogés, comme les publications avec le type de publication, vous pouvez demander uniquement les titres :

 query { authors(country: 'Nigeria') { country, posts { title } } }

Et il devrait renvoyer tout type d'auteur correspondant au Nigeria renvoyant le tableau country and posts contenant des objets avec uniquement le champ de titre.

Gatsby avec GraphQL

Pour éviter la surcharge d'avoir un serveur/service qui sert des données que GraphQL peut transformer, Gatsby exécute des requêtes GraphQL au moment de la construction. Les données sont fournies aux composants pendant le processus de construction, ce qui les rend facilement disponibles dans le navigateur sans serveur.

Pourtant, Gatsby peut fonctionner comme un serveur qui peut être interrogé par d'autres clients GraphQL, comme GraphiQL, dans un navigateur.

Manières Gatsby d'interagir avec GraphQL

Il existe deux endroits où Gatsby peut interagir avec GraphQL, via un fichier API gatsby-node.js et via des composants de page.

gatsby-node.js

L'API createPage peut être configurée comme une fonction qui recevra un assistant graphql dans le cadre des éléments du premier argument passé à la fonction.

 // gatsby-node.js source: https://www.gatsbyjs.org/docs/node-apis/#createPages exports.createPages = async ({ graphql, actions }) => { const result = await graphql(` query loadPagesQuery ($limit: Int!) { allMarkdownRemark(limit: $limit) { edges { node { frontmatter { slug } } } } }`) }

Dans le code ci-dessus, nous avons utilisé l'assistant GraphQL pour récupérer les fichiers de démarquage de la couche de données de Gatsby. Et nous pouvons l'injecter pour créer une page et modifier les données existantes dans la couche de données Gatsby.

Composants de la page

Les composants de page à l'intérieur du répertoire /pages ou les modèles rendus par l'action d'API createPage peuvent importer graphql à partir du module gatsby et exporter un pageQuery . À son tour, Gatsby injecterait de nouvelles data d'accessoires dans les accessoires du composant de page contenant les données résolues.

 import React from "react"; import { graphql } from "gatsby"; const Page = props => { return
{JSON.stringify(props.data)}
; } ; export const pageRequête = graphql` mettre en doute { ... } `; exporter la page par défaut ;

Dans d'autres composants

D'autres composants peuvent importer des composants graphql et StaticQuery à partir du module gatsby , restituer les accessoires de requête de transmission <StaticQuery/> qui implémentent l'assistant Graphql et restituer pour obtenir les données renvoyées.

 import React from "react"; import { StaticQuery, graphql } from "gatsby"; const Brand = props => { return ( <div> <h1>{data.site.siteMetadata.title}</h1> </div> ); }; const Navbar = props => { return ( <StaticQuery query={graphql` query { site { siteMetadata { title } } } `} render={data => <Brand data={data} {...props} />} /> ); }; export default Navbar;

Construire un blog d'édition Gatsby moderne et avancé

Dans cette section, nous allons parcourir un processus de création d'un blog prenant en charge le balisage, la catégorisation, la pagination et le regroupement des articles par auteurs. Nous utiliserons des plugins de l'écosystème de Gatsby pour apporter certaines fonctionnalités et utiliser des logiques dans les requêtes GraphQL pour créer un blog d'éditeur prêt pour les publications de plusieurs auteurs.

La version finale du blog que nous allons construire peut être trouvée ici, le code est également hébergé sur Github.

Initialisation du projet

Comme tout site Web Gatsby, nous initialisons à partir d'un démarreur, ici nous utiliserons le démarreur avancé mais modifié pour répondre à notre cas d'utilisation.

Clonez d'abord ce dépôt Github, changez la branche de travail en dev-init, puis exécutez npm run develop à partir du dossier du projet pour démarrer le serveur de développement rendant le site disponible à https://localhost:8000.

 git clone [email protected]:limistah/modern-gatsby-starter.git cd modern-gatsby-starter git checkout dev-init npm install npm run develop

La visite de https://localhost:8000 affichera la page d'accueil par défaut de cette branche.

Création de contenu d'articles de blog

Certains contenus de publication inclus dans le référentiel du projet sont accessibles via la branche dev-blog-content. L'organisation du répertoire de contenu ressemble à ceci /content/YYYY_MM/DD.md , qui regroupe les publications par mois de l'année créé.

Le contenu de l'article de blog a le title , la date , l' author , category , les tags comme frontmater, que nous utiliserons pour distinguer un article et effectuer un traitement supplémentaire, tandis que le reste du contenu est le corps de l'article.

 title: "Bold Mage" date: "2020-07-12" author: "Tunde Isiaka" category: "tech" tags: - programming - stuff - Ice cream - other --- # Donut I love macaroon chocolate bar Oat cake marshmallow lollipop fruitcake I love jelly-o. Gummi bears cake wafer chocolate bar pie. Marshmallow pastry powder chocolate cake candy chupa chups. Jelly beans powder souffle biscuit pie macaroon chocolate cake. Marzipan lemon drops chupa chups sweet cookie sesame snaps jelly halvah.

Afficher le contenu de la publication

Avant de pouvoir afficher nos publications Markdown en HTML, nous devons effectuer un traitement. Tout d'abord, chargez les fichiers dans le stockage Gatsby, analysez le MD en HTML, liez les dépendances d'image et aimez. Pour faciliter cela, nous utiliserons une multitude de plugins de l'écosystème Gatsby.

Nous pouvons utiliser ces plugins en mettant à jour le gatsby-config.js à la racine du projet pour qu'il ressemble à ceci :

 module.exports = { siteMetadata: {}, plugins: [ { resolve: "gatsby-source-filesystem", options: { name: "assets", path: `${__dirname}/static/`, }, }, { resolve: "gatsby-source-filesystem", options: { name: "posts", path: `${__dirname}/content/`, }, }, { resolve: "gatsby-transformer-remark", options: { plugins: [ { resolve: `gatsby-remark-relative-images`, }, { resolve: "gatsby-remark-images", options: { maxWidth: 690, }, }, { resolve: "gatsby-remark-responsive-iframe", }, "gatsby-remark-copy-linked-files", "gatsby-remark-autolink-headers", "gatsby-remark-prismjs", ], }, }, ], };

Nous avons demandé à gatsby d'inclure les plugins pour nous aider à effectuer certaines actions, notamment en extrayant des fichiers du dossier /static pour les fichiers statiques et /content pour nos articles de blog. De plus, nous avons inclus un plug-in de transformation de remarque pour transformer tous les fichiers se terminant par .md ou .markdown en un nœud avec tous les champs de remarque pour rendre le markdown au format HTML.

Enfin, nous avons inclus des plugins en opérant sur les nœuds générés par gatsby-transformer-remark .

Implémentation du fichier API gatsby-config.js

À l'avenir, à l'intérieur de gatsby-node.js à la racine du projet, nous pouvons exporter une fonction nommée createPage et avoir le contenu de la fonction pour utiliser l'assistant graphQL pour extraire les nœuds de la couche de contenu de GatsbyJS.

La première mise à jour de cette page consisterait à s'assurer que nous avons un slug défini sur les nœuds de remarque MarkDown. Nous écouterons l'API onCreateNode et créerons le nœud pour déterminer s'il s'agit d'un type de MarkdownRemark avant de mettre à jour le nœud pour inclure un slug et une date en conséquence.

 const path = require("path"); const _ = require("lodash"); const moment = require("moment"); const config = require("./config"); // Called each time a new node is created exports.onCreateNode = ({ node, actions, getNode }) => { // A Gatsby API action to add a new field to a node const { createNodeField } = actions; // The field that would be included let slug; // The currently created node is a MarkdownRemark type if (node.internal.type === "MarkdownRemark") { // Recall, we are using gatsby-source-filesystem? // This pulls the parent(File) node, // instead of the current MarkdownRemark node const fileNode = getNode(node.parent); const parsedFilePath = path.parse(fileNode.relativePath); if ( Object.prototype.hasOwnProperty.call(node, "frontmatter") && Object.prototype.hasOwnProperty.call(node.frontmatter, "title") ) { // The node is a valid remark type and has a title, // Use the title as the slug for the node. slug = `/${_.kebabCase(node.frontmatter.title)}`; } else if (parsedFilePath.name !== "index" && parsedFilePath.dir !== "") { // File is in a directory and the name is not index // eg content/2020_02/learner/post.md slug = `/${parsedFilePath.dir}/${parsedFilePath.name}/`; } else if (parsedFilePath.dir === "") { // File is not in a subdirectory slug = `/${parsedFilePath.name}/`; } else { // File is in a subdirectory, and name of the file is index // eg content/2020_02/learner/index.md slug = `/${parsedFilePath.dir}/`; } if (Object.prototype.hasOwnProperty.call(node, "frontmatter")) { if (Object.prototype.hasOwnProperty.call(node.frontmatter, "slug")) slug = `/${_.kebabCase(node.frontmatter.slug)}`; if (Object.prototype.hasOwnProperty.call(node.frontmatter, "date")) { const date = moment(new Date(node.frontmatter.date), "DD/MM/YYYY"); if (!date.isValid) console.warn(`WARNING: Invalid date.`, node.frontmatter); // MarkdownRemark does not include date by default createNodeField({ node, name: "date", value: date.toISOString() }); } } createNodeField({ node, name: "slug", value: slug }); } };

La liste des articles

À ce stade, nous pouvons implémenter l'API createPages pour rechercher toutes les démarques et créer une page avec le chemin comme le slug que nous avons créé ci-dessus. A voir sur Github.

 //gatsby-node.js // previous code // Create Pages Programatically! exports.createPages = async ({ graphql, actions }) => { // Pulls the createPage action from the Actions API const { createPage } = actions; // Template to use to render the post converted HTML const postPage = path.resolve("./src/templates/singlePost/index.js"); // Get all the markdown parsed through the help of gatsby-source-filesystem and gatsby-transformer-remark const allMarkdownResult = await graphql(` { allMarkdownRemark { edges { node { fields { slug } frontmatter { title tags category date author } } } } } `); // Throws if any error occur while fetching the markdown files if (allMarkdownResult.errors) { console.error(allMarkdownResult.errors); throw allMarkdownResult.errors; } // Items/Details are stored inside of edges const postsEdges = allMarkdownResult.data.allMarkdownRemark.edges; // Sort posts postsEdges.sort((postA, postB) => { const dateA = moment( postA.node.frontmatter.date, siteConfig.dateFromFormat ); const dateB = moment( postB.node.frontmatter.date, siteConfig.dateFromFormat ); if (dateA.isBefore(dateB)) return 1; if (dateB.isBefore(dateA)) return -1; return 0; }); // Pagination Support for posts const paginatedListingTemplate = path.resolve( "./src/templates/paginatedListing/index.js" ); const { postsPerPage } = config; if (postsPerPage) { // Get the number of pages that can be accommodated const pageCount = Math.ceil(postsEdges.length / postsPerPage); // Creates an empty array Array.from({ length: pageCount }).forEach((__value__, index) => { const pageNumber = index + 1; createPage({ path: index === 0 ? `/posts` : `/posts/${pageNumber}/`, component: paginatedListingTemplate, context: { limit: postsPerPage, skip: index * postsPerPage, pageCount, currentPageNumber: pageNumber, }, }); }); } else { // Load the landing page instead createPage({ path: `/`, component: landingPage, }); } };

Dans la fonction createPages , nous utilisons l'assistant graphql fourni par Gatsby pour interroger les données de la couche de contenu. Nous avons utilisé une requête Graphql standard pour ce faire et passé une requête pour obtenir le contenu de tous les types allMarkdownRemark . Puis avancé pour trier les publications par date de création.

Nous avons ensuite extrait une propriété postPerPage d'un objet de configuration importé, qui est utilisée pour réduire le nombre total de publications au nombre spécifié de publications pour une seule page.

Pour créer une page de liste prenant en charge la pagination, nous devons transmettre la limite, le numéro de page et le nombre de pages à ignorer au composant qui rendrait la liste. Nous y parvenons en utilisant la propriété context de l'objet de configuration createPage . Nous accéderons à ces propriétés à partir de la page pour effectuer une autre requête graphql afin de récupérer les publications dans la limite.

Nous pouvons également remarquer que nous utilisons le même composant de modèle pour la liste, et seul le chemin change en utilisant l'index du tableau de blocs que nous avions défini à l'avance. Gatsby transmettra les données nécessaires pour une URL donnée correspondant à /{chunkIndex} , nous pouvons donc avoir / pour les dix premiers articles et /2 pour les dix articles suivants.

Page d'accueil du blog moderne
Page d'accueil du blog moderne ( Grand aperçu )

Rendu de la publication de la liste

Le composant rendant ces pages se trouve dans src/templates/singlePost/index.js du dossier du projet. Il exporte également un assistant graphql qui extrait la limite et le paramètre de requête de page qu'il a reçu du processus createPages pour interroger gatsby pour les publications dans la plage de la page actuelle.

 import React from "react"; import { graphql, Link } from "gatsby"; import Layout from "../../layout"; import PostListing from "../../components/PostListing"; import "./index.css"; const Pagination = ({ currentPageNum, pageCount }) => { const prevPage = currentPageNum - 1 === 1 ? "/" : `/${currentPageNum - 1}/`; const nextPage = `/${currentPageNum + 1}/`; const isFirstPage = currentPageNum === 1; const isLastPage = currentPageNum === pageCount; return ( <div className="paging-container"> {!isFirstPage && <Link to={prevPage}>Previous</Link>} {[...Array(pageCount)].map((_val, index) => { const pageNum = index + 1; return ( <Link key={`listing-page-${pageNum}`} to={pageNum === 1 ? "/" : `/${pageNum}/`} > {pageNum} </Link> ); })} {!isLastPage && <Link to={nextPage}>Next</Link>} </div> ); }; export default (props) => { const { data, pageContext } = props; const postEdges = data.allMarkdownRemark.edges; const { currentPageNum, pageCount } = pageContext; return ( <Layout> <div className="listing-container"> <div className="posts-container"> <PostListing postEdges={postEdges} /> </div> <Pagination pageCount={pageCount} currentPageNum={currentPageNum} /> </div> </Layout> ); }; /* eslint no-undef: "off" */ export const pageQuery = graphql` query ListingQuery($skip: Int!, $limit: Int!) { allMarkdownRemark( sort: { fields: [fields___date], order: DESC } limit: $limit skip: $skip ) { edges { node { fields { slug date } excerpt timeToRead frontmatter { title tags author category date } } } } } `;

La page de publication

Pour afficher le contenu d'une page, nous devons créer la page par programmation dans le fichier API gatsby-node.js . Premièrement, nous devons définir un nouveau composant pour restituer le contenu avec, pour cela, nous avons src/templates/singlePost/index.jsx .

 import React from "react"; import { graphql, Link } from "gatsby"; import _ from "lodash"; import Layout from "../../layout"; import "./b16-tomorrow-dark.css"; import "./index.css"; import PostTags from "../../components/PostTags"; export default class PostTemplate extends React.Component { render() { const { data, pageContext } = this.props; const { slug } = pageContext; const postNode = data.markdownRemark; const post = postNode.frontmatter; if (!post.id) { post.id = slug; } return ( <Layout> <div> <div> <h1>{post.title}</h1> <div className="category"> Posted to{" "} <em> <Link key={post.category} style={{ textDecoration: "none" }} to={`/category/${_.kebabCase(post.category)}`} > <a>{post.category}</a> </Link> </em> </div> <PostTags tags={post.tags} /> <div dangerouslySetInnerHTML={{ __html: postNode.html }} /> </div> </div> </Layout> ); } } /* eslint no-undef: "off" */ export const pageQuery = graphql` query BlogPostBySlug($slug: String!) { markdownRemark(fields: { slug: { eq: $slug } }) { html timeToRead excerpt frontmatter { title date category tags } fields { slug date } } } `;

Encore une fois, nous utilisons un assistant graphQL pour extraire une page par une requête slug qui serait envoyée à la page via l'API createPages.

Ensuite, nous devrions ajouter le code ci-dessous à gatsby-node.js à la fin de la fonction API createPages .

 // Template to use to render the post converted HTML const postPage = path.resolve("./src/templates/singlePost/index.jsx"); // Loops through all the post nodes postsEdges.forEach((edge, index) => { // Create post pages createPage({ path: edge.node.fields.slug, component: postPage, context: { slug: edge.node.fields.slug, }, }); });

Et nous pourrions visiter '/{pageSlug}' et lui faire restituer le contenu du fichier de démarquage pour cette page au format HTML. Par exemple, https://localhost:8000/the-butterfly-of-the-edge doit charger le code HTML converti pour le démarquage à : content/2020_05/01.md , similaire à tous les slugs valides. Génial!

Page de publication de blog moderne
Page de publication de blog moderne ( Grand aperçu )

Catégories et balises de rendu

Le composant de modèle de publication unique contient un lien vers une page au format /categories/{categoryName} pour répertorier les publications avec des catégories similaires.

Nous pouvons d'abord capturer toutes les catégories et balises lorsque nous construisons la page de publication unique dans le fichier gatsby-node.js , puis créer des pages pour chaque catégorie/balise capturée en passant le nom de la catégorie/balise.

Une modification de la section pour créer une page de publication unique dans gatsby-node.js ressemble à ceci :

 const categorySet = new Set(); const tagSet = new Set(); const categoriesListing = path.resolve( "./src/templates/categoriesListing/index.jsx" ); // Template to use to render posts based on categories const tagsListingPage = path.resolve("./src/templates/tagsListing/index.jsx"); // Loops through all the post nodes postsEdges.forEach((edge, index) => { // Generate a list of categories if (edge.node.frontmatter.category) { categorySet.add(edge.node.frontmatter.category); } // Generate a list of tags if (edge.node.frontmatter.tags) { edge.node.frontmatter.tags.forEach((tag) => { tagSet.add(tag); }); } // Create post pages createPage({ path: edge.node.fields.slug, component: postPage, context: { slug: edge.node.fields.slug, }, }); });

Et à l'intérieur du composant de liste des publications par balises, nous pouvons avoir la requête d'exportation pageQuery graphql pour les publications, y compris cette balise dans sa liste de balises. Nous utiliserons la fonction de filter de graphql et l'opérateur $in pour y parvenir :

 // src/templates/tagsListing/ import React from "react"; import { graphql } from "gatsby"; import Layout from "../../layout"; import PostListing from "../../components/PostListing"; export default ({ pageContext, data }) => { const { tag } = pageContext; const postEdges = data.allMarkdownRemark.edges; return ( <Layout> <div className="tag-container"> <div>Posts posted with {tag}</div> <PostListing postEdges={postEdges} /> </div> </Layout> ); }; /* eslint no-undef: "off" */ export const pageQuery = graphql` query TagPage($tag: String) { allMarkdownRemark( limit: 1000 sort: { fields: [fields___date], order: DESC } filter: { frontmatter: { tags: { in: [$tag] } } } ) { totalCount edges { node { fields { slug date } excerpt timeToRead frontmatter { title tags author date } } } } } `;

Et nous avons le même processus dans le composant de liste des catégories, et la différence est que nous avons seulement besoin de trouver où les catégories correspondent précisément à ce que nous lui transmettons.

 // src/templates/categoriesListing/index.jsx import React from "react"; import { graphql } from "gatsby"; import Layout from "../../layout"; import PostListing from "../../components/PostListing"; export default ({ pageContext, data }) => { const { category } = pageContext; const postEdges = data.allMarkdownRemark.edges; return ( <Layout> <div className="category-container"> <div>Posts posted to {category}</div> <PostListing postEdges={postEdges} /> </div> </Layout> ); }; /* eslint no-undef: "off" */ export const pageQuery = graphql` query CategoryPage($category: String) { allMarkdownRemark( limit: 1000 sort: { fields: [fields___date], order: DESC } filter: { frontmatter: { category: { eq: $category } } } ) { totalCount edges { node { fields { slug date } excerpt timeToRead frontmatter { title tags author date } } } } } `;

Remarquable, à l'intérieur des composants des balises et des catégories, nous rendons des liens vers la page de publication unique pour une lecture plus approfondie du contenu d'une publication.

Page de publication unique Hello World avec étiquette
Article moderne avec catégorie étiquetée ( Grand aperçu )

Ajout de la prise en charge des auteurs

Pour prendre en charge plusieurs auteurs, nous devons apporter quelques modifications au contenu de nos publications et introduire de nouveaux concepts.

Charger les fichiers JSON

Tout d'abord, nous devrions pouvoir stocker le contenu des auteurs dans un fichier JSON comme celui-ci :

 { "mdField": "aleem", "name": "Aleem Isiaka", "email": "[email protected]", "location": "Lagos, Nigeria", "avatar": "https://api.adorable.io/avatars/55/[email protected]", "description": "Yeah, I like animals better than people sometimes... Especially dogs. Dogs are the best. Every time you come home, they act like they haven't seen you in a year. And the good thing about dogs... is they got different dogs for different people.", "userLinks": [ { "label": "GitHub", "url": "https://github.com/limistah/modern-gatsby-starter", "iconClassName": "fa fa-github" }, { "label": "Twitter", "url": "https://twitter.com/limistah", "iconClassName": "fa fa-twitter" }, { "label": "Email", "url": "mailto:[email protected]", "iconClassName": "fa fa-envelope" } ] }

Nous les stockerions dans le répertoire d'un auteur à la racine de notre projet en tant que /authors . Notez que l'auteur JSON a mdField qui serait l'identifiant unique du champ auteur que nous allons introduire dans le contenu du blog Markdown ; cela garantit que les auteurs peuvent avoir plusieurs profils.

Ensuite, nous devons mettre à jour les plugins gatsby-config.js demandant gatsby-source-filesystem de charger le contenu du répertoire author authors/ dans le nœud Files.

 // gatsby-config.js { resolve: `gatsby-source-filesystem`, options: { name: "authors", path: `${__dirname}/authors/`, }, }

Enfin, nous installerons gatsby-transform-json pour transformer les fichiers JSON créés pour une manipulation facile et un traitement approprié.

 npm install gatsby-transformer-json --save

Et incluez-le dans les plugins de gatsby-config.js ,

 module.exports = { plugins: [ // ...other plugins `gatsby-transformer-json` ], };

Interroger et créer une page d'auteurs

Pour commencer, nous devons interroger tous les auteurs de notre répertoire author authors/ à l'intérieur de gatsby-config.js qui ont été chargés dans la couche de données, nous devons ajouter le code ci-dessous à la fonction API createPages

 const authorsListingPage = path.resolve( "./src/templates/authorsListing/index.jsx" ); const allAuthorsJson = await graphql(` { allAuthorsJson { edges { node { id avatar mdField location name email description userLinks { iconClassName label url } } } } } `); const authorsEdges = allAuthorsJson.data.allAuthorsJson.edges; authorsEdges.forEach((author) => { createPage({ path: `/authors/${_.kebabCase(author.node.mdField)}/`, component: authorsListingPage, context: { authorMdField: author.node.mdField, authorDetails: author.node, }, }); });

Dans cet extrait, nous extrayons tous les auteurs du type allAuthorsJson, puis appelons forEach sur les nœuds pour créer une page où nous passons le mdField pour distinguer l'auteur et le authorDetails pour des informations complètes sur l'auteur.

Rendu des messages de l'auteur

Dans le composant rendant la page qui se trouve à src/templates/authorsListing/index.jsx , nous avons le contenu ci-dessous pour le fichier

 import React from "react"; import { graphql } from "gatsby"; import Layout from "../../layout"; import PostListing from "../../components/PostListing"; import AuthorInfo from "../../components/AuthorInfo"; export default ({ pageContext, data }) => { const { authorDetails } = pageContext; const postEdges = data.allMarkdownRemark.edges; return ( <Layout> <div> <h1 style={{ textAlign: "center" }}>Author Roll</h1> <div className="category-container"> <AuthorInfo author={authorDetails} /> <PostListing postEdges={postEdges} /> </div> </div> </Layout> ); }; /* eslint no-undef: "off" */ export const pageQuery = graphql` query AuthorPage($authorMdField: String) { allMarkdownRemark( limit: 1000 sort: { fields: [fields___date], order: DESC } filter: { frontmatter: { author: { eq: $authorMdField } } } ) { totalCount edges { node { fields { slug date } excerpt timeToRead frontmatter { title tags author date } } } } } `;

Dans le code ci-dessus, nous avons exporté la pageQuery comme nous le faisons, pour créer une requête GraphQL pour récupérer les publications correspondant à un auteur, nous utilisons l'opérateur $eq pour y parvenir en générant des liens vers une seule page de publication pour une lecture plus approfondie.

Page d'auteur de blog moderne
Page d'auteur de blog moderne ( Grand aperçu )

Conclusion

Dans Gatsby, nous pouvons interroger toutes les données qui existent à l'intérieur de sa couche d'accès aux données à l'aide de la requête GraphQL et transmettre des variables à l'aide de certaines constructions définies par l'architecture de Gatsby. nous avons vu comment nous pourrions utiliser l'assistant graphql à divers endroits et comprendre les modèles largement utilisés pour interroger les données sur les sites Web de Gatsby à l'aide de GraphQL.

GraphQL est très puissant et pourrait faire d'autres choses comme la mutation de données sur un serveur. Gatsby n'a pas besoin de mettre à jour ses données au moment de l'exécution, il ne prend donc pas en charge la fonctionnalité de mutation de GraphQL.

GraphQL est une excellente technologie, et Gatsby la rend très intéressante à utiliser dans leur framework.

Les références

  • Prise en charge de Gatsby pour GraphQL
  • Pourquoi Gatsby utilise GraphQL
  • Concepts GraphQL dans Gatsby
  • Comment utiliser GraphQL : concepts de base
  • Langage de définition de schéma dans GraphQL
  • Une introduction à GraphQL
  • Démarreur avancé Gatsby