API Query Language

GraphQL

GraphQL permet aux clients de demander exactement les données dont ils ont besoin, en une seule requête. Un schéma typé décrit l'API, et des resolvers récupèrent les données correspondantes.

intermediate14 min readUpdated 15 sept. 2026
query.graphql
graphql
// query.graphql
query UserWithPosts($id: ID!) {
  user(id: $id) {
    name
    posts(first: 3) {
      title
    }
  }
}
Créé par
Facebook, 2012
Sortie
2015, open source
Schéma
Un contrat typé
Opérations
Query, mutation, subscription
Transport
Généralement HTTP, un seul endpoint
Serveur
Resolvers derrière le schéma

Pourquoi c'est important

Pourquoi les équipes adoptent GraphQL

Demandez ce dont vous avez besoin

Les clients sélectionnent les champs exacts qu'ils utilisent, ainsi les réponses ne souffrent ni d'over-fetching ni d'under-fetching.

Une requête, plusieurs ressources

Une seule requête peut traverser des relations qui nécessiteraient autrement plusieurs allers-retours REST.

Un contrat typé

Le schéma est auto-documenté et permet l'autocomplétion, la validation et la génération de code.

Le tableau complet

Les trois piliers de GraphQL

Un schéma typé décrit les données, une requête sélectionne exactement ce qui est nécessaire, et des resolvers fournissent chaque champ.

Le schéma

Contrat

Types, champs et opérations qui décrivent exactement ce que l'API peut retourner.

La requête

Sélection

Un document client qui sélectionne des champs et passe des arguments et des variables.

Les resolvers

Résolution

Fonctions qui récupèrent les données pour chaque champ, souvent depuis des bases de données ou des services.

GraphQL en un coup d'œil

Le cœur de GraphQL

Types et schéma

Types d'objets, scalaires, enums, interfaces et unions.

Queries

Lecture de données en sélectionnant des champs depuis le type de requête racine.

Mutations

Écriture de données, avec une entrée explicite et une forme de retour définie.

Subscriptions

Flux de mises à jour en temps réel via une connexion persistante.

Variables et fragments

Réutilisation des sélections de champs et passage d'arguments typés.

Clients

Apollo, urql et Relay gèrent la mise en cache et les requêtes.

Un bref aperçu

D'une API interne Facebook à un standard industriel

  1. 2012

    Développé chez Facebook

    Facebook crée GraphQL pour alimenter ses applications mobiles avec une récupération de données efficace.

    12
  2. 2015

    Passage en open source

    La spécification et l'implémentation de référence sont publiées publiquement.

    15
  3. 2018

    Création de la fondation

    La GraphQL Foundation est créée pour administrer la spécification.

    18
  4. 2020

    Adoption généralisée

    Apollo, urql et Relay maturent, et GraphQL devient courant dans les API de produits.

    20
  5. Aujourd'hui

    Un outil standard

    Largement utilisé pour les API publiques, les services internes et les graphes fédérés.

    Aujourd'hui

Le guide complet

GraphQL: Tout ce que vous devez savoir

Qu’est-ce que GraphQL ?

GraphQL est un langage de requête et un runtime pour les API. Au lieu d’exposer de nombreux endpoints fixes, un serveur GraphQL expose un unique schema typé, et les clients envoient des requêtes pour sélectionner précisément les champs dont ils ont besoin. Le serveur résout chaque champ et renvoie une réponse dont la structure correspond exactement à la requête.

Facebook l’a conçu en 2012 pour résoudre un problème lié au mobile : les endpoints REST renvoyaient soit trop de données, soit pas assez, et récupérer toutes les informations liées à un écran nécessitait de multiples allers-retours. GraphQL a corrigé ces deux problèmes en permettant au client de décrire ses besoins en données dans un seul document.

Le schéma

Le schéma est le contrat. Il définit les types ainsi que les opérations disponibles.

# schema.graphql
type User {
  id: ID!
  name: String!
  email: String
  posts(first: Int = 10): [Post!]!
}

type Post {
  id: ID!
  title: String!
  body: String!
  author: User!
}

type Query {
  user(id: ID!): User
  posts(limit: Int): [Post!]!
}

type Mutation {
  createPost(input: CreatePostInput!): Post!
}

Le symbole ! marque un champ comme non nul. Les types s’organisent en graphe, c’est pourquoi une seule requête peut naviguer d’un utilisateur vers ses articles, puis revenir vers les auteurs. Le schéma est introspectable, ce qui permet aux outils de générer automatiquement la documentation, les types et l’autocomplétion.

Requêtes

Une requête sélectionne des champs à partir du type de requête racine, en utilisant des arguments et des variables.

# posts.graphql
query RecentPosts($limit: Int!) {
  posts(limit: $limit) {
    id
    title
    author {
      name
    }
  }
}

La réponse reflète exactement la sélection : aucun champ supplémentaire, aucun champ manquant. Les variables permettent de rendre les requêtes réutilisables et permettent au serveur de valider les types d’arguments. Les fragments permettent d’extraire des sélections répétées pour les réutiliser.

# fragment.graphql
fragment PostCard on Post {
  id
  title
  author { name }
}

query Feed {
  posts { ...PostCard }
}

Mutations et subscriptions

Une mutation modifie des données et renvoie une structure définie, incluant souvent l’objet mis à jour afin que le client puisse actualiser son cache.

# create.graphql
mutation CreatePost($input: CreatePostInput!) {
  createPost(input: $input) {
    id
    title
  }
}

Une subscription diffuse des mises à jour en temps réel via une connexion persistante, comme pour de nouveaux messages ou des notifications en direct. Utilisez-la lorsque le serveur doit pousser des données vers le client ; pour des rafraîchissements occasionnels, le polling ou un refetch est plus simple.

Resolvers

Les resolvers sont le point de rencontre entre votre schéma et vos données. Chaque champ possède un resolver qui retourne sa valeur.

// resolvers.js
const resolvers = {
  Query: {
    user: (_parent, { id }, { db }) => db.users.findById(id),
    posts: (_parent, { limit = 10 }, { db }) => db.posts.findMany({ limit }),
  },
  User: {
    posts: (user, { first }, { db }) =>
      db.posts.findMany({ where: { authorId: user.id }, limit: first }),
  },
  Mutation: {
    createPost: (_parent, { input }, { db }) => db.posts.create(input),
  },
};

L’objet context transporte les ressources partagées, telles que la base de données et l’utilisateur authentifié. Les resolvers doivent rester concis, et les vérifications d’autorisation doivent être effectuées ici ou dans la couche de service qu’ils appellent — jamais côté client.

Le problème N+1

Le piège de performance le plus courant avec GraphQL est le problème des requêtes N+1. Si une requête retourne dix articles et que le resolver de l’auteur de chaque article interroge la base de données, vous exécutez onze requêtes.

DataLoader résout ce problème en regroupant (batching) et en mettant en cache les appels au sein d’une seule requête.

// loaders.js
import DataLoader from "dataloader";

function createUserLoader(db) {
  return new DataLoader(async (ids) => {
    const users = await db.users.findByIds(ids);
    return ids.map((id) => users.find((u) => u.id === id));
  });
}

Le resolver de l’auteur appelle ensuite loaders.user.load(post.authorId), et DataLoader regroupe tous les chargements du tick en une seule requête. C’est l’optimisation la plus importante pour un serveur GraphQL.

Clients et mise en cache

Les bibliothèques client telles qu’Apollo Client et urql gèrent la mise en cache, la normalisation, les états de chargement et d’erreur, ainsi que l’intégration avec les frameworks UI. Un cache normalisé stocke les entités par type et par id ; ainsi, une mutation qui renvoie un post mis à jour actualise automatiquement toutes les requêtes qui y faisaient référence.

Comme GraphQL utilise généralement un unique point de terminaison POST, la mise en cache HTTP est moins efficace qu’avec REST. Les clients compensent cela avec des caches normalisés, et les serveurs utilisent des requêtes persistantes (persisted queries) et la mise en cache des réponses. Concevez vos mutations pour qu’elles renvoient les objets modifiés afin que le cache client puisse rester cohérent.

GraphQL ou REST ?

GraphQL est idéal lorsque :

  • Les clients ont besoin de champs différents selon les écrans.
  • Un écran nécessite des données provenant de nombreuses ressources liées.
  • Vous souhaitez une API unique, typée et auto-documentée.

REST est plus simple quand :

  • Les ressources correspondent clairement à des endpoints.
  • Le cache HTTP et les codes de statut sont primordiaux.
  • L’API est petite et stable.

De nombreuses équipes utilisent les deux, en privilégiant GraphQL pour l’API produit et REST pour les webhooks, l’upload de fichiers et les endpoints publics simples.

Bonnes pratiques

  • Concevez le schéma en fonction des besoins du client, et non des tables de la base de données.
  • Utilisez les types non-null de manière réfléchie et gérez les versions du schéma via des dépréciations.
  • Gardez vos resolvers légers et déportez la logique métier dans des services.
  • Résolvez le problème N+1 avec DataLoader dès le départ.
  • Ajoutez des limites de profondeur et de complexité aux requêtes pour éviter les abus.
  • Retournez les objets modifiés depuis les mutations pour garantir la cohérence du cache.
  • Utilisez des requêtes persistantes (persisted queries) en production pour réduire la taille des payloads.

Erreurs courantes

  • Exposer directement le schéma de la base de données comme schéma GraphQL.
  • Ignorer le problème N+1 jusqu’à l’effondrement des performances.
  • Récupérer toutes les données dans chaque requête, perdant ainsi l’avantage principal.
  • Faire confiance à l’autorisation fournie par le client ou aux permissions au niveau des champs.
  • Construire des requêtes profondément imbriquées sans limite de profondeur.
  • Supposer que le cache HTTP fonctionne de la même manière qu’avec REST.

Et après ?

GraphQL est un moyen puissant de concevoir des API centrées sur les clients. Appuyez-vous sur le protocole HTTP, construisez le serveur avec Node.js et consommez-le depuis React à l’aide d’une bibliothèque client. Ensuite, modélisez un écran que vous connaissez bien sous forme de schéma et de requête, et observez avec quelle fluidité les besoins en données sont satisfaits.

Demande de données

GraphQL retourne exactement les champs sélectionnés. Les endpoints REST retournent souvent bien plus que ce dont le client a besoin, gaspillant ainsi la bande passante et le temps de parsing.

Préférer
query {
  user(id: "1") {
    name
    avatar
  }
}
// only name and avatar
// cross the wire
Éviter
// GET /users/1 returns
// the entire user record,
// including fields the
// client never displays

Récupération de données liées

Une seule requête GraphQL peut traverser des relations, évitant ainsi les multiples allers-retours qu'un client REST devrait effectuer.

Préférer
query {
  user(id: "1") {
    name
    posts(first: 3) {
      title
      comments { text }
    }
  }
}
Éviter
# three requests:
# /users/1
# /users/1/posts
# /posts/:id/comments

FAQ

Foire aux questions

Keep learning

Related topics from the roadmap.

$ commencer à apprendre

Prêt à apprendre GraphQL ?

Notre tutoriel interactif vous guide à travers GraphQL pas à pas — avec des quiz et du vrai code que vous pouvez exécuter dans le navigateur.