Gatsby
,GraphQL
Typer vos données avec Gatsby et Graphql
Comment typer proprement vos données en gatsby et graphql, afin d'éviter les erreurs de compilations pour les données manquantes.
Murat
25 février 2021
Dans cet article, je vais vous parler un peu de mon expérience avec gatsby, et des limitations qui m’ont un peu surpris lorsque je commencer à jouer un peu plus avec le code.
Le typage des données
Vous avez monté votre blog, et pour chacun des posts vous utilisez MarkdownRemark
. La structure de votre fichier .md
ressemble à ceci :
# content/blog/article-blog.md---draft: falsepermalink: article-blogtags:- Helloauthors:- SnowPacttitle: Mon article de Blogdate: 2021-01-30T07:03:47.149Zexcerpt: Ma description SEOimage: ../assets/default.jpgfooter: Le mot de la fin---# Mon titre## Mon contenu markdown...
Dans votre page template, vous avez sûrement une requête graphql de ce type
"""src/templates/post.tsx"""query($slug: String, $primaryTag: String) {markdownRemark(fields: { slug: { eq: $slug } }) {htmlhtmlAstexcerpttimeToReadparent {... on File {modifiedTime}}frontmatter {titledatetagsfooterdraftexcerptimage {childImageSharp {fluid(maxWidth: 2000) {...GatsbyImageSharpFluid}}}authors {id}}}
Lorsque vous avez quelques articles, vous éxecutez un gatsby build
ou un gatsby develop
, le projet compile bien et vous avez vos premiers post bien générés.
Maintenant modifiez la propriété footer
de tous vos fichiers, et mettez les à vide. Et la qu’est-ce qu’il se passe quand vous essayez de recompiler ?
Erreur !
Comment gatsby vous mets à disposition les données de vos fichiers de sources ?
Le simple fait d’avoir une propriété à vide (null
réellement), peut faire planter votre compilation. Pourquoi ?
Ce qu’il se passe en fait lors du build, c’est que Gatsby va parcourir toute vos sources de données, et "inférer"
les données. Il va vérifier dans chaque node
ce que vous avez, et créer le typage graphql. C’est l’étape du Schema Inference.
Pour illustrer avec le cas précédent, si aucun fichier comporte un footer
avec une donnée, Graphql ne mettra pas à disposition de propriété footer
lors de vos query
, et boom ça plantera.
En d’autres mots, si vous avez une données “nullable”, et qu’aucun des fichiers a une valeur pour cette donnée, alors adieu la compilation !
La solution : createSchemaCustomization
Mais tout n’est pas peine perdu. Gatsby met à votre disposition une page qui vous explique comment régler ce soucis.
Ça se passe dans le fichier gatsby-node.js
, lors de l’étape createSchemaCustomization
, et ça ressemble à ça :
// gatsby-node.jsexports.createSchemaCustomization = ({ actions }) => {const { createTypes } = actionsconst typeDefs = `type AuthorJson implements Node {joinedAt: Date}`createTypes(typeDefs)}
Gatsby met à votre disposition une méthode createTypes
qui permet de typer votre objet. Si on applique cela à notre objet que nous avions précédemment :
// gatsby-node.jsexports.createSchemaCustomization = ({ actions }) => {const typeDefs = `type MarkdownRemark implements Node @infer {frontmatter: FrontmatterfileAbsolutePath: Stringfields: Fields}type Frontmatter {draft: Boolean!permalink: String!author: [AuthorYaml!]! @linktags: [String]title: String!date: Dateexcerpt: String!footer: Stringimage: File! @fileByRelativePath}type Fields {slug: String!}`;
Ce qu’il se passe ici, c’est que vous indiquer à Gatsby le typage des données attendus. Vous devez commencer par l’objet qui héritera de Node
(ici MarkdownRemark
). Dedans se trouve notre frontmatter à qui on va créer un type Frontmatter
, et spécifier les données.
Bref, j’imagine que vous avez déjà compris sans expliquer ce que ça fait. Je vais juste vous expliquer les différentes annotations / types présents :
Typage Graphql et Gatsby
NOMTYPEDESCRIPTION@infer
Annotation(optionnel) Indique à gatsby qu’il peut inférer également les données de ce type@dontInfer
AnnotationIndique à gatsby que nous sommes sûr de ce type, et qu’on ne veut pas qu’il parcours les données. Cela fera economiser du temps de build pour les plus gros projets@link
AnnotationPermet de linker avec une autre source de donnée, en le liant à la propriété id
de l’autre côté@fileByRelativePath
AnnotationPermet de lier à une image locale lorsque vous avez un lien relatif. C’est ce que gatsby fait par défaut pour vos imagesBoolean
TypeValeur de type booleanString
TypeValeur de type stringDate
TypeValeur de type date[XXX]
TypeTableau de type XXX!
TypeA la fin d’un type, le !
permet d’indiquer que cette valeur ne peut pas être null
Bien entendu vous pouvez créer vos types comme on l’a vu plus haut.
@link
vs mapping
On va revenir sur le @link
. Vous avez sûrement dans votre projet des auteurs, un AuthorYml
ou AuthorJson
, que vous allez unir avec vos articles.
Et vous avez également peut-être dans votre fichier gatsby-config.js
, cette propriété mapping proposée par gatsby pour rendre disponible automatiquement dans vos requêtes qui vise le blog, l’auteur lié directement :
module.exports = {...,mapping: {'MarkdownRemark.frontmatter.author': 'AuthorYaml',},};
Exemple :
frontmatter {...authors {idavatar}}
Mon conseil, enlever cette partie et utiliser plutôt @link
. Cela permet de faire la même chose, avec le bénéfice de pouvoir gérer les auteurs null
.
Conclusion
Si vous aimez réellement Gatsby, et que vous commencez à vous intéresser un peu plus, alors il est sûr à 100% que vous allez rencontrer ce problème.
Alors prenez bien le temps de lire cet article, et commencez à typer vos données dès maintenant !
Technologies dans cet article ...
Front-End
Gatsby
D'autres articles dans la même catégorie...