GraphQL
GraphQL[1] (pour Graph Query Language) est un langage de requĂȘtes et un environnement d'exĂ©cution, crĂ©Ă© par Facebook en 2012, avant d'ĂȘtre publiĂ© comme projet open-source en 2015[2]. Inscrit dans le modĂšle Client-Serveur, il propose une alternative aux API REST[1]. La requĂȘte du client dĂ©finit une structure de donnĂ©es, dont le stockage est Ă©ventuellement distribuĂ©, et le serveur suit cette structure pour retourner la rĂ©ponse[3]. Fortement typĂ©, ce langage Ă©vite les problĂšmes de retour de donnĂ©es insuffisants (under-fetching) ou surnumĂ©raires (over-fetching).
GraphQL | ||
Date de premiĂšre version | 2012 (Facebook) | |
---|---|---|
Paradigmes | déclaratif, procédural, orienté objet | |
DĂ©veloppeurs | The GraphQL Foundation | |
Influencé par | JavaScript Object Notation Hypertext Transfer Protocol |
|
Implémentations | Facebook, ArangoDB, Credit Karma, GitHub, Intuit, PayPal, New York Times | |
Ăcrit en | JavaScript, Ruby, Scala, Python entre autres. | |
SystĂšme d'exploitation | Multiplateforme | |
Licence | Open-source (depuis 2015) | |
Site web | graphql.org | |
Extension de fichier | graphql | |
Principe
Une API GraphQL permet de rĂ©cupĂ©rer des donnĂ©es en fonction de la requĂȘte client. En REST, c'est la mĂ©thode de requĂȘte HTTP (GET, POST,...), l'URL ou encore les paramĂštres envoyĂ©s qui dĂ©finissent les fonctions mĂ©tiers Ă appeler et la nature du retour. GraphQL le fait directement avec la requĂȘte envoyĂ©e en POST. Comme les requĂȘtes POST ne sont pas mises en cache cĂŽtĂ© serveur, les requĂȘtes GraphQL doivent ĂȘtre mises en cache cĂŽtĂ© client[4].
Langage de requĂȘtes
La particularité de GraphQL est que la structure de la réponse du serveur est fixée par le client (conformément aux limites de l'API). Par exemple, c'est lui qui décide des champs qu'il souhaite pour chaque Objet, et dans quel ordre il veut les recevoir.
Prenons la situation d'un fournisseur de fruits & lĂ©gumes. Il dispose d'une API GraphQL lui permettant d'obtenir toutes les commandes qu'on lui a effectuĂ© et leurs dĂ©tails. Lorsqu'il consulte sa plateforme de gestion, son navigateur adresserait la requĂȘte suivante via la mĂ©thode POST :
{
orders {
id
productsList {
product {
name
price
}
quantity
}
totalAmount
}
}
AprÚs traitement de la réponse par l'API (dont le client n'a pas forcément connaissance), le serveur répondrait comme suit :
{
"data": {
"orders": [
{
"id": 0,
"productsList": [
{
"product": {
"name": "orange",
"price": 1.5
},
"quantity": 100
}
],
"totalAmount": 150
}
]
}
}
Dans cet exemple, un produit peut possĂ©der beaucoup plus d'attributs que simplement le nom et le prix. Mais dans notre situation, le fournisseur n'a pas besoin de plus d'informations que ça. De cette maniĂšre, l'utilisation de GraphQL a permis au client de se passer des informations inutiles, et donc de gagner du temps et des ressources. Le problĂšme de donnĂ©es surnumĂ©raires, dit over-fetching, a ainsi Ă©tĂ© Ă©vitĂ©. De mĂȘme, l'API GraphQL a garanti l'obtention de toutes les informations nĂ©cessaires Ă la consultation du fournisseur, ce qu'une API REST n'aurait pas forcĂ©ment permis en une requĂȘte seulement. Cette fois, c'est le problĂšme de donnĂ©es insuffisantes, ou under-fetching, qui a Ă©tĂ© Ă©vitĂ©.
Environnement d'exécution
Une API GraphQL est organisĂ©e grĂące aux Types et Champs. Pour dĂ©clarer l'ensemble de ces Ă©lĂ©ments, le fournisseur de donnĂ©es doit construire le squelette de l'API. C'est ce schĂ©ma qu'il partagera avec tous les clients qu'il souhaite, sans qu'ils aient besoin de savoir comment les donnĂ©es ont Ă©tĂ© rĂ©cupĂ©rĂ©es. Dans l'exemple prĂ©cĂ©dent, le schĂ©ma pourrait ĂȘtre celui-ci :
type Query {
orders: [Order]
}
type Product {
id: Int!
name: String
weight: Float
price: Float
}
type Order {
id: Int!
productsList: [
product: Product
quantity: Int
]
totalAmount: Int
}
Le premier Type, Query, contient toutes les requĂȘtes de consultation admises par l'API. Dans l'exemple, on retrouve la rĂšgle orders, qui permet de recevoir un ensemble d'objets Order. Un autre Type existe aussi, Mutation, contenant toutes les rĂšgles de mise Ă jour des donnĂ©es, comme les insertions par exemple. Les deux blocs suivants dĂ©finissent les structures de objets Product et Order. Comme expliquĂ© dans la section prĂ©cĂ©dente, le client pourra demander tous les attributs de chaque type, ou moins.
Ă travers la dĂ©claration du squelette de l'API, on comprend mieux l'appellation du langage : GraphQL. En effet, une rĂ©ponse conforme au schĂ©ma de l'exemple peut ĂȘtre reprĂ©sentĂ©e par l'arbre ci-contre. Un premier niveau de l'arbre contient toutes les commandes (orders). Ă chaque branche order, on retrouve d'autres sous-divisions product, correspondant aux champs productsList. Dans une API REST, il aurait par exemple fallu demander la liste des commandes, puis pour chaque commande, demander les produits qui y appartiennent. Dans l'idĂ©e, la structure arborescente de GraphQL devient plus avantageuse quand l'arbre devient plus profond. Le langage a peu de limites puisqu'il est capable de prendre en charge des relations beaucoup plus complexes, avec des objets interdĂ©pendants par exemple.
Attention Ă la confusion : le nom de Graph Query Language ne vient pas du fait que GraphQL est destinĂ© aux bases de donnĂ©es orientĂ©es graphes, mais bien de la structure arborescente des rĂ©ponses aux requĂȘtes. Il ne faut donc surtout pas confondre GraphQL avec GQL.
Utilisations
GraphQL a Ă©tĂ© implĂ©mentĂ© pour de nombreux langages, par exemple Graphene[5] pour Python, Apollo[6] et Relay[7] pour Javascript. Il est utilisĂ© par certaines bases de donnĂ©es orientĂ©es graphe comme ArangoDB en tant que langage de requĂȘte[8].
Facebook est le premier instigateur de GraphQL. En effet, les applications iOS Ă©taient souvent confrontĂ©es Ă des saturations de la consommation des donnĂ©es. Une application mobile doit donc prendre en compte la possibilitĂ© que l'utilisateur ait une faible bande passante, ce qui se traduit par un besoin de rĂ©duire au minimum le nombre d'appels Ă une API ainsi que la quantitĂ© de donnĂ©es transmises. Le principal avantage de GraphQL est ainsi de pouvoir fournir une application via une requĂȘte unique, en dĂ©lĂ©guant au serveur la tĂąche de structurer les donnĂ©es. On Ă©pargne ainsi au client des Ă©changes rĂ©seau multiples, ce qui autorise un gain de temps apprĂ©ciable.
Inconvénients
Du fait que la structure d'une rĂ©ponse d'une API GraphQL est personnalisable par le client, l'utilisation d'un cache cĂŽtĂ© serveur est peu envisageable. En effet, les requĂȘtes et leurs rĂ©ponses dĂ©pendent du client.
Références
- (en) « GraphQL: A query language for APIs. »
- « GraphQL: A data query language »
- Romain Calamier, « GraphQL: Et pour quoi faire ? », sur blog.octo.com,
- « GraphQL & Caching : The Elephant in the Room », sur Apollo GraphQL Blog (consulté le ).
- « GraphQL in Python made simple »
- (en) « Page d'accueil d'Apollo GraphQL »
- (en) « Introduction to Relay », sur https://facebook.github.io/
- « Using GraphQL with NoSQL database ArangoDB »