Architecture
ArchitectureUtiliser des composants plutôt que des graphes

Utiliser des composants plutôt que des graphes

Gato GraphQL n'utilise pas les graphes pour représenter le modèle de données. À la place, il utilise des composants.

Ce n'est pas une approche inattendue. Sous le titre Thinking in Graphs, le projet GraphQL déclare (emphase ajoutée) :

Les graphes sont des outils puissants pour modéliser de nombreux phénomènes du monde réel, car ils ressemblent à nos modèles mentaux naturels et aux descriptions verbales du processus sous-jacent. Avec GraphQL, vous modélisez votre domaine métier comme un graphe en définissant un schéma ; au sein de votre schéma, vous définissez différents types de nœuds et la façon dont ils se connectent/se relient les uns aux autres. Du côté client, cela crée un patron similaire à la Programmation Orientée Objet : des types qui font référence à d'autres types. Du côté serveur, puisque GraphQL ne définit que l'interface, vous avez la liberté de l'utiliser avec n'importe quel backend (nouveau ou hérité !).

Ce qu'il faut retenir de cette définition, c'est que :

Même si la réponse a la forme d'un graphe, cela ne signifie pas que les données sont réellement représentées comme un graphe lors de leur traitement côté serveur. Le graphe n'est qu'un modèle mental, pas une implémentation réelle.

C'est une bonne nouvelle, car travailler avec des graphes (ou des arbres) n'est pas trivial. Les composants, en revanche, sont beaucoup plus simples à implémenter et offrent exactement les mêmes avantages.

Simplifier le modèle de données grâce aux composants

Utiliser des composants pour représenter la structure des données côté serveur est optimal en termes de simplicité, car cela permet de consolider les différents modèles pour nos données en une seule structure. Au lieu d'avoir un flux comme celui-ci :

construire une requête pour alimenter les composants (client) => traiter les données comme un graphe/arbre (serveur) => alimenter les données aux composants (client)

...notre flux sera comme ceci :

composants (client) => composants (serveur) => composants (client)

Ceci est réalisable parce que la requête GraphQL peut être conçue comme ayant une structure de données de « hiérarchie de composants », dans laquelle chaque type d'objet représente un composant, et chaque champ de relation d'un type d'objet à un autre type d'objet représente un composant enveloppant un autre composant.

Utilisons un exemple pour visualiser cette relation entre composant et requête GraphQL. Supposons que nous voulions construire le widget « Réalisateur en vedette » suivant :

Widget Réalisateur en vedette

En utilisant Vue ou React (ou toute autre bibliothèque basée sur les composants), nous identifierions d'abord les composants. Dans ce cas, nous aurions un composant extérieur <FeaturedDirector> (en rouge), qui enveloppe un composant <Film> (en bleu), qui lui-même enveloppe un composant <Actor> (en vert) :

Identification des composants dans le widget

Le pseudo-code ressemblera à ceci :

<!-- Component: <FeaturedDirector> -->
<div>
  Country: {country}
  {foreach films as film}
    <Film film={film} />
  {/foreach}
</div>
 
<!-- Component: <Film> -->
<div>
  Title: {title}
  Pic: {thumbnail}
  {foreach actors as actor}
    <Actor actor={actor} />
  {/foreach}
</div>
 
<!-- Component: <Actor> -->
<div>
  Name: {name}
  Photo: {avatar}
</div>

Ensuite, nous identifions quelles données sont nécessaires pour chaque composant. Pour <FeaturedDirector> nous avons besoin de name, avatar et country. Pour <Film> nous avons besoin de thumbnail et title. Et pour <Actor> nous avons besoin de name et avatar :

Identification des propriétés de données pour chaque composant

Et nous construisons notre requête GraphQL pour récupérer les données requises :

query {
  featuredDirector {
    name
    country
    avatar
    films {
      title
      thumbnail
      actors {
        name
        avatar
      }
    }
  }
}

Comme on peut l'apprécier, il existe une relation directe entre la hiérarchie de composants ci-dessus et cette requête GraphQL.