GraphQL
GraphQL est un langage de requête et un runtime d’exécution pour les API, créé par Facebook en 2012 et open-sourcé en 2015, qui permet au client de demander exactement les données dont il a besoin, ni plus ni moins, en une seule requête via un endpoint unique.
Le problème que GraphQL résout est simple. Avec une REST API, vous recevez ce que le serveur décide de vous envoyer : souvent trop de données (over-fetching) ou pas assez (under-fetching, nécessitant plusieurs requêtes). Avec GraphQL, le client spécifie la structure exacte de la réponse qu’il veut. Vous demandez le nom et l’email d’un utilisateur, vous recevez exactement le nom et l’email, pas ses 50 autres attributs. C’est un changement fondamental : le client contrôle la forme des données.
- Catégorie
- Langage de requête pour API
- Créateur
- Facebook (Meta), 2012, open-source 2015
- Gouvernance
- GraphQL Foundation (Linux Foundation)
- Transport
- HTTP POST (endpoint unique)
- Format
- JSON (réponse), langage GraphQL (requête)
- Implémentations
- Apollo (JS), Strawberry/Graphene (Python), graphql-java
- Utilisé par
- GitHub, Shopify, Stripe, Airbnb, Twitter/X
Les concepts fondamentaux
Schema et types
Le schema GraphQL est le contrat entre le client et le serveur. Il définit les types de données disponibles, les relations entre eux, et les opérations possibles. Le schema utilise un système de types fort : chaque champ a un type défini, ce qui permet la validation automatique et l’auto-documentation.
type User {
id: ID!
name: String!
email: String!
posts: [Post!]!
createdAt: DateTime!
}
type Post {
id: ID!
title: String!
content: String!
author: User!
comments: [Comment!]!
publishedAt: DateTime
}
type Query {
user(id: ID!): User
users(limit: Int, offset: Int): [User!]!
post(id: ID!): Post
}
type Mutation {
createUser(input: CreateUserInput!): User!
updatePost(id: ID!, input: UpdatePostInput!): Post!
deletePost(id: ID!): Boolean!
}Le ! indique un champ obligatoire (non-null). [Post!]! signifie une liste non-null de Post non-null. Ce système de types élimine une catégorie entière de bugs liés aux données manquantes ou malformées.
Queries (lecture)
Une query GraphQL spécifie exactement les champs souhaités. Le serveur retourne une réponse JSON qui correspond à la structure de la requête :
# Requête : demander uniquement nom et email
query {
user(id: "123") {
name
email
}
}
# Réponse JSON
{
"data": {
"user": {
"name": "Alice Martin",
"email": "alice@example.com"
}
}
}En REST, l’endpoint GET /users/123 retournerait probablement 20 champs. En GraphQL, vous ne recevez que les 2 que vous avez demandés. Sur mobile (bande passante limitée, batterie), cette précision fait une différence mesurable.
Mutations (écriture)
Les mutations sont les opérations d’écriture (création, mise à jour, suppression). Comme les queries, elles permettent de spécifier les champs retournés après l’opération :
mutation {
createUser(input: {
name: "Bob Dupont"
email: "bob@example.com"
}) {
id
name
createdAt
}
}Subscriptions (temps réel)
Les subscriptions permettent au client de recevoir des mises à jour en temps réel quand les données changent, typiquement via WebSocket. C’est l’équivalent GraphQL du Server-Sent Events ou du polling, mais intégré nativement dans le langage :
subscription {
newComment(postId: "456") {
id
content
author {
name
}
}
}Resolvers
Les resolvers sont les fonctions côté serveur qui récupèrent les données pour chaque champ du schema. Un resolver peut interroger une base de données, appeler une REST API, lire un cache, ou combiner plusieurs sources de données. C’est là que GraphQL brille comme couche d’agrégation : un seul endpoint peut fédérer des données provenant de multiples backends.
Pourquoi utiliser GraphQL
Pas d’over-fetching ni d’under-fetching. Le client demande exactement ce dont il a besoin. Pas de données inutiles transférées, pas de requêtes multiples pour assembler les données nécessaires. Un seul aller-retour réseau au lieu de 3-5 appels REST.
Système de types fort. Le schema est le contrat. Les erreurs de typage sont détectées avant l’exécution. Les outils de développement (auto-complétion, validation) fonctionnent grâce au schema. La documentation est auto-générée via l’introspection du schema.
Évolution sans versionnement. GraphQL encourage l’ajout de nouveaux champs sans supprimer les anciens. Les champs obsolètes sont marqués @deprecated avec une raison. Les clients existants continuent de fonctionner pendant que les nouveaux utilisent les champs améliorés. Pas besoin de /v1/, /v2/ comme en REST.
Fragments pour les composants UI. Les fragments permettent à chaque composant frontend de déclarer ses besoins en données. La requête finale est composée en assemblant les fragments. C’est l’intégration naturelle de GraphQL avec les architectures à composants (React, Vue).
Introspection. Le schema GraphQL est interrogeable par les clients. Des outils comme GraphiQL et Apollo Studio permettent d’explorer l’API interactivement, sans documentation externe.
Les limites de GraphQL
Complexité serveur. Le serveur doit résoudre des requêtes arbitraires, ce qui peut créer des problèmes de performance (N+1 queries) et de sécurité (requêtes profondément imbriquées). Dataloader et les query cost analyzers sont nécessaires pour mitiger ces risques.
Cache plus difficile. REST exploite nativement le cache HTTP (chaque URL est cachable). GraphQL utilise un seul endpoint POST, ce qui rend le cache HTTP standard impossible. Vous devez utiliser un cache applicatif (Apollo Client normalize cache) ou un cache au niveau des resolvers.
Upload de fichiers. GraphQL n’a pas de support natif pour l’upload de fichiers. Des spécifications comme graphql-multipart-request-spec existent, mais c’est un point de friction par rapport à REST.
Courbe d’apprentissage. Le langage de requête, le schema, les resolvers, le dataloader, la gestion du cache client : la stack GraphQL est plus complexe à mettre en place qu’une simple REST API. Cette complexité n’est justifiée que si vous avez des besoins réels de flexibilité dans les données.
GraphQL vs REST : quand choisir quoi
| Critère | Choisir GraphQL | Choisir REST |
|---|---|---|
| Clients multiples | Mobile + web + partenaires avec des besoins différents | Un ou deux clients avec des besoins similaires |
| Données | Relations complexes, données imbriquées | CRUD simple, ressources plates |
| Performance réseau | Bande passante limitée (mobile), latence critique | Bande passante abondante (backend-to-backend) |
| Évolution API | Itérations rapides, besoins qui changent fréquemment | API stable avec des versions clairement définies |
| Cache | Cache applicatif acceptable | Cache HTTP CDN nécessaire |
| Équipe | Frontend fort qui veut contrôler ses données | Backend fort qui contrôle les endpoints |
| Complexité acceptable | Oui (schema, resolvers, dataloader) | Minimale souhaitée |
La règle pragmatique : si votre application a un seul frontend avec des besoins de données prévisibles, REST est plus simple et suffisant. Si vous avez des applications mobile et web avec des besoins de données très différents, ou si vos frontends évoluent vite et demandent régulièrement de nouveaux champs, GraphQL justifie sa complexité additionnelle.
L’écosystème GraphQL
| Catégorie | Outil | Description |
|---|---|---|
| Serveur JS/TS | Apollo Server, GraphQL Yoga | Frameworks serveur GraphQL pour Node.js |
| Client JS/TS | Apollo Client, urql, Relay | Clients avec cache normalisé et gestion d’état |
| Serveur Python | Strawberry, Graphene, Ariadne | Implémentations Python (Strawberry est le plus moderne) |
| Exploration | GraphiQL, Apollo Studio, Insomnia | IDE interactifs pour explorer et tester les requêtes |
| Performance | Dataloader, Persisted Queries | Optimisation du N+1 et sécurité/performance |
| Federation | Apollo Federation, GraphQL Mesh | Combiner plusieurs services GraphQL en un seul schema |
GraphQL et IA
GraphQL est moins courant que REST pour les API d’IA et de ML. Les API des fournisseurs LLM (OpenAI, Anthropic, Google) sont toutes REST. Cependant, GraphQL trouve sa place dans les couches applicatives qui orchestrent des services IA :
BFF (Backend for Frontend) devant des services ML. Un serveur GraphQL peut agréger les résultats de plusieurs modèles ML (classification, embedding, génération) en une seule réponse adaptée au frontend, évitant les appels multiples.
API de produit qui intègrent de l’IA. GitHub (GraphQL API) intègre Copilot, Shopify (GraphQL API) intègre des fonctionnalités de recommandation IA. Le frontend récupère les données produit et les résultats ML dans la même requête.
Subscriptions pour le streaming LLM. Les subscriptions GraphQL via WebSocket sont une alternative aux SSE pour streamer les réponses de LLM token par token, avec l’avantage du typage fort du schema.
GraphQL Federation : architecture microservices
Dans une architecture microservices, chaque service gère un domaine métier. Apollo Federation permet de combiner les schemas GraphQL de plusieurs services en un seul schema unifié, exposé par un gateway. Chaque service (appelé « subgraph ») définit son propre schema et ses propres resolvers, et le gateway (Apollo Router) compose les requêtes et les distribue aux services concernés.
Par exemple, un service Users gère les types User, un service Orders gère les types Order, et un service Products gère les types Product. Le gateway expose un schema unifié où un client peut demander un User avec ses Orders et les Products de chaque Order, en une seule requête. Le gateway décompose cette requête en sous-requêtes vers chaque service et assemble la réponse.
C’est la réponse GraphQL au problème de composition des données dans une architecture distribuée. Chaque équipe possède son subgraph, peut le déployer indépendamment, et le gateway maintient la cohérence globale. GitHub, Netflix et Expedia utilisent cette approche en production.
Exemple pratique : requête client complète
Voici un exemple concret qui illustre la puissance de GraphQL par rapport à REST. Imaginez une page de profil utilisateur qui affiche le nom, les 5 derniers posts avec leurs titres, et le nombre total de commentaires :
# En GraphQL : UNE seule requête
query UserProfile {
user(id: "123") {
name
email
avatarUrl
posts(last: 5) {
title
publishedAt
commentCount
}
stats {
totalPosts
totalComments
memberSince
}
}
}En REST, cette même page nécessiterait typiquement 3 appels : GET /users/123 (données utilisateur), GET /users/123/posts?limit=5 (posts récents), et GET /users/123/stats (statistiques). Trois aller-retours réseau au lieu d’un seul, et chaque réponse contient potentiellement des champs inutiles. Sur un réseau mobile avec 200ms de latence par requête, la différence entre 200ms (une requête GraphQL) et 600ms (trois requêtes REST) est perceptible pour l’utilisateur.
Le code client (React avec Apollo Client) est également plus propre, car chaque composant déclare ses besoins en données via un fragment, et la requête finale est composée automatiquement.
Sécurité GraphQL
GraphQL introduit des vecteurs d’attaque spécifiques que REST n’a pas :
Requêtes profondément imbriquées. Un client malveillant peut construire une requête avec 50 niveaux d’imbrication, saturant le serveur. Implémentez une limite de profondeur (query depth limiting) et un budget de coût par requête (query cost analysis).
Introspection en production. L’introspection expose la structure complète de votre API. Désactivez-la en production si votre API n’est pas publique.
Persisted queries. Au lieu de permettre des requêtes arbitraires, pré-enregistrez les requêtes autorisées et acceptez uniquement des identifiants de requête. Cela élimine les requêtes malveillantes et réduit le payload réseau.
Erreurs courantes
Utiliser GraphQL pour tout. GraphQL n’est pas supérieur à REST par défaut. Pour une API CRUD simple avec un seul client, REST est plus rapide à implémenter et plus facile à maintenir. N’adoptez GraphQL que si le problème d’over/under-fetching est réel dans votre contexte.
Pas de Dataloader. Sans Dataloader (ou équivalent), chaque requête GraphQL qui traverse des relations produit un problème N+1. C’est la cause numéro 1 de la lenteur des serveurs GraphQL.
Schema trop permissif. Un schema qui expose toutes les données de votre base sans contrôle d’accès est une faille de sécurité. Implémentez l’autorisation au niveau des resolvers (pas uniquement au niveau du endpoint) et utilisez des directives custom comme @auth pour marquer les champs qui nécessitent une authentification ou un rôle spécifique.
Pas de limites de requête. Sans depth limiting et cost analysis, un utilisateur peut construire une requête qui consomme des ressources serveur disproportionnées. Configurez une profondeur maximale (typiquement 5-10 niveaux), un coût maximal par requête, et un timeout. Les plateformes comme Shopify implémentent un système de « query cost points » qui limite la complexité des requêtes de manière granulaire.
Ignorer la performance des resolvers. Chaque resolver est une fonction qui peut faire des appels réseau ou des requêtes SQL. Loguez et monitorez le temps d’exécution de chaque resolver en production pour identifier les goulots d’étranglement.
Questions fréquentes sur GraphQL
Quelle est la différence entre GraphQL et REST ?
REST expose des ressources via des endpoints (URL) multiples avec une structure de réponse fixe définie par le serveur. GraphQL utilise un endpoint unique où le client spécifie exactement les champs souhaités. REST utilise les méthodes HTTP (GET, POST, PUT, DELETE) pour les actions, GraphQL utilise queries (lecture) et mutations (écriture). REST bénéficie du cache HTTP natif, GraphQL nécessite un cache applicatif. Les deux coexistent souvent dans une même application.
GraphQL remplace-t-il REST ?
Non. GraphQL est une alternative qui résout des problèmes spécifiques (over-fetching, under-fetching, clients multiples avec des besoins différents). REST reste le choix dominant pour les API publiques, les intégrations simples et les services backend-to-backend. En 2026, REST domine largement en adoption, GraphQL est en croissance régulière pour les frontends complexes. Beaucoup d’organisations utilisent les deux : GraphQL pour les clients frontends, REST pour les intégrations et les webhooks.
Quels sont les meilleurs outils pour démarrer avec GraphQL ?
En JavaScript/TypeScript, Apollo Server (serveur) et Apollo Client (client) forment la stack la plus populaire. En Python, Strawberry est le framework le plus moderne (type hints natifs, intégration FastAPI). Pour l’exploration, GraphiQL est l’IDE interactif de référence. Commencez par un schema simple (2-3 types, quelques queries), ajoutez Dataloader dès que vous avez des relations, et implémentez le depth limiting avant de passer en production.
GraphQL est-il utilisé pour les API d’IA ?
Très peu directement. Les API des fournisseurs LLM (OpenAI, Anthropic, Google, Mistral) sont toutes REST. GraphQL est plus pertinent dans la couche applicative : un serveur GraphQL peut agréger les résultats de plusieurs modèles ML, combiner des données produit avec des résultats d’inférence, et utiliser les subscriptions pour le streaming des réponses LLM via WebSocket.
Quelles entreprises utilisent GraphQL en production ?
GitHub (toute l’API v4), Shopify (API Admin et Storefront), Airbnb, Twitter/X, PayPal, Netflix, Pinterest, et la majorité des applications React à grande échelle. Facebook/Meta l’utilise en interne depuis 2012. La GraphQL Foundation (Linux Foundation) gère la spécification. L’adoption est particulièrement forte dans l’écosystème React/React Native où Apollo Client et Relay sont largement déployés.