Maîtrisez React

Découvrez React et son écosystème, quel que soit votre niveau.

Découverte de GraphQL : présentation et premières requêtes

April 21, 2019

Premier article d’une série consacrée à GraphQL, dans laquelle après avoir présenté le langage et ce qu’il apporte par rapport à REST, nous verrons comment mettre en place notre propre API GraphQL ainsi qu’une application React y faisant appel pour persister des données.

Il y a quelques années, pour appeler une API distante, la référence en terme de moyen technique pour y parvenir était SOAP, avec lequel on encapsulait requêtes et résultats dans de verbeux flux XML. Puis est arrivé REST qui redonnait sa place aux basiques d’HTTP et profitait du JSON pour décrire les échanges. Beaucoup plus simple à appréhender que SOAP, les développeurs web notamment n’ont pas mis longtemps à l’adopter.

Aujourd’hui, c’est un nouveau moyen de requêter une API qui fait parler de lui : GraphQL. Explorons dans cette série d’articles ce qu’il apporte en développant une application React faisant appel à une API GraphQL pour persister des données.

Qu’est-ce que GraphQL ?

Pour faire simple, GraphQL est une convention pour échanger des données entre un client (un front-end React par exemple) et un serveur (Node.js, PHP…). À la base d’une API GraphQL, on trouve donc :

  • la description des objets pouvant être retournés par une requête : par exemple un utilisateur comporterait un ID numérique, un nom, une date de naissance, tandis qu’un article aurait comme champs un ID, un titre, un contenu textuel, et une référence vers l’utilisateur l’ayant créé ;
  • la description des méthodes qui peuvent être appelées sur l’API, avec les paramètres d’entrée de ces méthodes, et la description de ce qu’elles renvoient. Elles-mêmes séparées en deux types :

    • les queries qui permettent de lire des données ;
    • les mutations pour créer, mettre à jour ou supprimer des données.

Afin de mieux comprendre ces notions, allons dès maintenant jouer avec une API GraphQL : celle de GitHub.

Premières requêtes avec l’API de GitHub

GitHub fournit un outil en ligne pour requêter directement son API GraphQL: son GraphQL API Explorer. Sur celui-ci, en haut à droite, cliquez sur le bouton « Docs » pour ouvrir le Documentation Explorer. Pour notre première requête, nous souhaitons récupérer des informations sur le repository GitHub de React. Il s’agit donc d’une requête en lecture (une query), cliquons donc sur « Query » pour obtenir la liste des queries disponibles, puis descendons jusqu’à la query repository et cliquons dessus pour avoir les détails.

doc
Documentation de la query repository

On apprend ici :

  • que la query attend deux paramètres : un owner et un name, tous deux de type chaîne de caractères (String), et tous deux requis (ceci est indiqué par le point d’exclamation après le type : !) ;
  • qu’elle renvoie un objet de type Repository. En cliquant sur ce type vous pourrez découvrir les nombreux champs qu’il contient.

Notez que cette documentation n’est pas juste un bout de page HTML statique, elle est en réalité générée automatiquement par l’API GraphQL. Elle est donc nécessairement toujours à jour avec l’implémentation de l’API. En quelque sorte on peut dire que la documentation fait partie intégrante de l’API elle-même.

Bien, donc nous souhaitons obtenir les informations sur le repository de React. Écrivons donc la requête : (je vous suggère de ne pas la copier-coller mais plutôt de l’écrire directement dans l’éditeur afin de contempler l’auto-complétion rendue disponible par GraphQL)

{
  repository(owner: "facebook", name: "react") {
    id
    nameWithOwner
    description
  }
}

Ici nous appelons donc la query repository, en lui passant les paramètres owner et name. Du résultat de cette requête, nous souhaitons obtenir les champs id, nameWithOwner et description. Que remarque-t-on de cette requête ?

  • D’abord la syntaxe est propre à GraphQL, même si on note des ressemblances avec JSON ou JavaScript. Elle est relativement simple à prendre en main, nous aurons l’occasion de voir plusieurs exemples par la suite ;
  • Ensuite, nous fournissons les données que nous souhaitons recevoir de cette requête. En effet il n’est pas possible de dire simplement que l’on souhaite tous les champs disponibles. Cela peut sembler être une contrainte au premier abord, mais cela garantit que vous aurez les champs attendus, ni plus ni moins, même si l’API est mise à jour.

En exécutant cette requête on obtient un résultat au format JSON :

req1
Résultat de la requête

Vous verrez que les résultats sont toujours au format suivant : un objet comportant un attribut data, étant lui-même un objet dont les clés sont les noms des queries appelées (on peut en effet appeler plusieurs queries dans un même appel).

Ajout de données liées à la requête

Ajoutons quelques données à notre requête ; nous souhaitons ajouter aux informations du repository la liste de ses issues. Pour cela l’API de GraphQL propose le champ issues sur le type Repository. Mais petite particularité de l’API GitHub : il ne s’agit pas d’un tableau mais d’un objet contenant notamment un attribut nodes, lui de type tableau.

{
  repository(owner: "facebook", name: "react") {
    id
    nameWithOwner
    description
    issues(last: 10) {
      nodes {
        number
        title
      }
    }
  }
}

Notez aussi que l’on peut passer des paramètres lorsqu’on récupère des données liées à un objet, comme les issues. En réalité l’API de GitHub nous impose de spécifier le dernier élément à récupérer (paramètre last), sans quoi une erreur est retournée.

req2
Requête avec les issues

Grâce à cette requête nous obtenons les informations que nous souhaitons sur le repository, avec les dix premières issues, et pour chacune, les données souhaitées uniquement : son numéro et son titre. Vous devriez commencer à voir les avantages du langage de requêtes GraphQL, même si cela peut paraître un brin magique…

Écrire des données

À présent que nous savons lire des données depuis l’API, intéressons-nous à la modification des données existantes au moyen des mutations. Dans la mesure où les données modifiées sont les « vraies » données de GitHub (ce n’est pas juste un bac à sable), soyons prudents et faisons une opération simple. Nous allons ajouter une étoile (star) au projet React.

Pour écrire une mutation, la syntaxe est similaire à une query, mais on placera le mot-clé mutation avant la première accolade (pour une query on peut mettre le mot-clé query mais ce n’est pas obligatoire).

mutation {
  addStar(input: { starrableId: "MDEwOlJlcG9zaXRvcnkxMDI3MDI1MA==" }) {
    clientMutationId
    starrable {
      id
    }
  }
}

Dans notre cas la mutation appelée est addStar, et la documentation nous apprend qu’elle prend en paramètre un objet input de type AddStarInput, lui-même comportant un attribut obligatoire starrableId, correspondant à l’ID de la ressource (ici un repository) sur laquelle on souhaite ajouter une étoile.

Comme pour une query, une mutation renvoie elle-même des données. Il est donc nécessaire de spécifier quelles données nous souhaitons récupérer, ici clientMutationId et l’attribut id de starrable.

Après avoir exécuté cette mutation vous pourrez constater que vous venez d’ajouter une étoile au projet React. Pour valider à nouveau, vous pourrez remplacer addStar par removeStar dans la requête 😉

Prochaines étapes

Maintenant que nous avons vu comment faire des queries et des mutations sur une API GraphQL, vous devriez commencer à sentir la puissance de ce langage de requêtes. Mais d’un autre côté il est possible que vous vous demandiez, parmi les fonctionnalités que nous venons de voir, lesquelles sont assurées par GraphQL, et lesquelles le sont par l’API GitHub spécifiquement.

En effet, en utilisant l’API de GitHub, on pourrait penser que GraphQL prend à sa charge des fonctionnalités comme le filtrage, la pagination, ou encore les jointures entre différents objets. En réalité il n’en est rien, GraphQL n’est ni plus ni moins que le langage permettant d’effectuer les requêtes, et de décrire ce qu’elles prennent en paramètres et renvoient en résultat. Tout le reste est bien de la responsabilité du serveur qui fournit l’API.

Afin de mieux comprendre cela, nous allons dans le prochain article de cette série voir comment créer notre propre API GraphQL pour stocker des données sur un serveur, le tout sans écrire la moindre ligne de code serveur. Cela nous permettra également d’aller un peu plus loin dans les possibilités offertes par les requêtes et les mutations.