Retour au Blog

GraphQL: Une API qui ne parle pas pour rien dire

Publié:

Pour les non développeurs

GraphQL est une façon de requêter des données via une interface web de type API.
Cette méthode a été ouverte au public par Facebook en 2015 (de façon Open Source) et est de plus en plus utilisée aujourd’hui notamment en dévelopement web. Elle offre la possibilité de définir de façon exacte les données échangeables, de demander exactement celles dont on a besoin et enfin de recevoir exactement ce qu’on a demandé. Cette méthode est donc plus flexible et évite de faire des transformations a posteriori.


Pour les développeurs

1. Pourquoi un nouveau protocole d'API web ?

GraphQL est une spécification open source publiée par Facebook en 2015 qui permet de requêter des données grâce au protocole http sur une interface API.


“ Demande ce que tu veux et obtient exactement ça. “


GraphQL n’utilise qu’un URL (ou endpoint) pour requêter, alors qu'avec une API REST (couramment utilisée) on se retrouve souvent avec un grand nombre d’URLs différentes qui renvoient des données très diverses autant sur le format que le contenu.
Il permet de créer un schéma pour décrire les types et le format des données. Ceci offre la possibilité de requêter exactement la structure de données voulue et de recevoir exactement ce qu’on demande, contrairement aux API REST qui ne permet pas (ou peu) de personnaliser les requêtes et avec lesquelles on peut avoir un gros volume de données en retour qu’il faut ensuite transformer et filtrer avant de pouvoir l’utiliser. En développement web il est aujourd'hui de plus en plus courant que ce soit le code exécuté sur le navigateur (En Front-End avec du javascript par exemple) qui demande à une API les données à afficher à l’utilisateur. GraphQL apporte donc dans ce cas plus de flexibilité et moins de mise en forme à faire. Son utilisation facilite également les discussions entre les équipes de développeurs Frontend et Backend car le Front a le schéma et requête ce dont il a besoin sans demander à développer des requêtes spécifiques comme on le voit avec les API REST.

Avec GraphQL, on modélise notre logique Business comme un graph. Il permet de modéliser notre donnée de façon naturelle en lien avec l'utilisation qu'il va en être faite. On définit dans le schéma différents types de noeuds et on les relie entre eux.

Ce type d’interface n’a pas de version, les évolutions sont plus simples et flexibles car il suffit de faire évoluer le schéma de données. De fait ça encourage les développeurs à n’implémenter que ce dont ils ont besoin. Le but du schéma et de faire retranscrire la logique métier qui sera utilisée par la personne qui demande la donnée au lieu de copier le schéma présent en base de données. Elle offre une facilité d’interopérabilité et permet plus facilement de changer de service utilisateur sans changer tout le Backend.

2. Comment ça marche ?

Différentes opérations sont permises: lire (via le type « Query »), écrire (avec une « Mutation ») et s’inscrire à des flux de données (opération de type « Subscription »).

Les données sont définies et décrites par un schéma. Ce système est typé, avec une sémantique et une validation des données requêtées et renvoyées grâce au schéma. Il définit tous les champs, types et tout ce qui peut être demandé. De plus le schéma est implémenté dans le langage GraphQL ce qui le rend indépendant du langage utilisé coté serveur GraphQL.

type Query {   
  human(id: ID!): Human 
}  

type Human {   
  name: String   
  appearsIn: [Episode]   
  starships: [Starship] 
}  

enum Episode {   NEWHOPE   EMPIRE   JEDI }  

type Starship {   
  name: String 
}
Exemple de schéma de données Star Wars
Les types permis pour les champs sont larges : Le schéma et les types permettent la validation mais sont aussi une contrainte car on est obligé de demander les champs définit en profondeur et pas de façon superficielle (exactement ce qu’on veut et on ne peut pas récupérer tous les attributs par exemple).

La Query définie précédemment représente toutes les entrées possibles dans l’API. Pour répondre les bonnes données on définit des « resolvers ».
Les resolvers sont des fonctions qui ‘résolvent’ les valeurs pour les différents champs définis dans le schéma. Leur rôle est de renvoyer la donnée requêtée lors d’une « Query », en se connectant par exemple à une base de données ou un fichier de type xls, csv, json .. etc . Ils peuvent être synchrones ou asynchrones selon s'il faut attendre une autre action asynchrone (comme par exemple une réponse d’une requête en base de données).
Ils prennent 4 arguments :

Query: {   
  human(obj, args, context, info) {     
    return  context.db.loadHumanByID(args.id)
      .then(       
        userData => new Human(userData)     
      )   
  } 
}
Exemple de resolver

Le serveur GraphQL se base sur le schéma et les resolvers pour éxécuter les Queries/Mutations/Subscriptions et par conséquent les données demandées.
Il répond sous le même format que la Query mais en JSON.
Par exemple la requête :

{
  human(id: 1002) {
    name
    appearsIn
    starships {
      name
    }
  }
}
répond :
{
  "data": {
    "human": {
      "name": "Han Solo",
      "appearsIn": [
        "NEWHOPE",
        "EMPIRE",
        "JEDI"
      ],
      "starships": [
        {
          "name": "Millenium Falcon"
        },
        {
          "name": "Imperial shuttle"
        }
      ]
    }
  }
}

Outil de debug «GraphiQL » : Cet outil permet de créer une documentation à partir du schéma et d'explorer les données de l'API. C'est équivalente à Postman qui est couramment utilisé avec REST. Il possède également l’autocomplétion pour aider à l’utilisation.

Exemple d'API REST
Outil GraphiQL permettant de tester l'API.

Authentification : il existe des règles et directives @AUTH sur les champs mais j’avoue que la mise en œuvre a été un peu laborieuse car elle dépend de l’avancement des librairies de chaque langage. Personnellement en Python ce n’était pas pris en compte et mal documenté donc j’ai dû m’adapter et contourner avec des tokens dans les requêtes HTTP sans utiliser la spécification GraphQL.

Les serveurs GraphQL peuvent être développés en plusieurs langages tels que Javascript, Python, Java, Go, Ruby… Ceci est rendu possible par le développement d’un large choix de librairies et packages par la communauté.

3. Application : GraphQL en Python

Il y a 4 principaux packages à date (Septembre 2020). Ceux ci implémentent avec plus ou moins de fidélité la spécification définie par Facebook. Il y en a qui sont plus ou moins flexibles mais la logique reste la même avec la définition d'un schéma de données et de resolvers.


Avis perso :
J'ai fait le choix d'utiliser Ariadne car il est plus bas niveau et me laisse bien séparer mon serveur web Flask de ma logique GraphQL. Ariadne n'était pas le package avec la plus grosse communauté sur stackoverflow ou Github, j'ai dû faire preuve d'imagination pour déboguer... Il me permet de définir un fichier schéma avec mon système typé exactement comme détaillé dans la specification de GraphQL.
Coté Front end je n'ai eu aucun soucis en utilisant Apollo pour requêter (React, Vue…) mais ce peut être fait avec JQuery ou les outils habituels permettant de faire des requêtes sur une API web.



Merci de votre lecture et n'hésitez pas à m'envoyer vos commentaires si vous avez eu une expérience avec GraphQL ou si vous voulez en savoir plus !

Florian

Retour au Blog