Skip to main content
LadeStack LogoLadeStack
Architecture 5 min de lecture 2 septembre 2024

REST vs GraphQL : Choisir le Bon Paradigme d'API pour les Systèmes en Production

Évaluation architecturale approfondie entre REST et GraphQL. Mise en cache HTTP sur les réseaux CDN, optimisation de la charge utile, problème N+1 et patron DataLoader.

Comparatif d'Architecture REST vs GraphQL

Le débat opposant REST (Representational State Transfer) à GraphQL s’est affranchi des querelles de clocher pour devenir une évaluation d’ingénierie rigoureuse, fondée sur les caractéristiques réelles des flux de données, les contraintes de mise en cache et la diversité des clients. Présenter GraphQL comme un remplaçant universel de REST occulte les principes fondateurs de chacun de ces modèles.

Dans ce dossier architectural, nous examinons les compromis techniques entre l’approche par ressources de REST et l’approche par graphe de GraphQL, résolvons le problème des requêtes N+1 et évaluons les stratégies de mise en cache HTTP en bordure de réseau (Edge CDN).


Deux Paradigmes d’Architecture : Ressource vs Graphe

Les deux architectures appréhendent l’accès aux données distribuées selon des philosophies fondamentalement divergentes :

REST (Centré sur les Ressources) :
GET /api/v1/users/42          ──► [Données utilisateur]
GET /api/v1/users/42/orders   ──► [Historique des commandes]
GET /api/v1/products/808      ──► [Détail du produit]
(Multiples allers-retours réseau ou points de terminaison composites volumineux)

GRAPHQL (Centré sur le Graphe) :
POST /graphql
{
  user(id: "42") {
    name
    orders { id total product { title price } }
  }
}                             ──► [Charge utile exacte en un seul aller-retour]

Le Modèle REST

REST structure le système sous forme de ressources autonomes identifiées par des URI universelles, manipulées via les méthodes HTTP standard (GET, POST, PUT, DELETE).

  • Forces : Adéquation naturelle avec le protocole HTTP, outillage universel, URI déterministes et intégration immédiate avec les réseaux de diffusion de contenu (CDN).
  • Faiblesses : Risque de sur-récupération (Over-fetching) de données et nécessité d’enchaîner plusieurs requêtes pour alimenter des vues composites (Under-fetching).

Le Modèle GraphQL

GraphQL introduit un schéma strictement typé et un langage de requête expressif, permettant au client d’extraire exactement les champs requis.

  • Forces : Élimination totale des transferts inutiles, agrégation de relations multiples en une requête unique et contrat d’interface rigoureux.
  • Faiblesses : Perte de la mise en cache HTTP native au niveau des URL, vulnérabilité face aux requêtes récursives non bornées et risque systématique de requêtes N+1.

Le Terrain de la Mise en Cache : Edge HTTP vs Cache Client Normalisé

En environnement à fort trafic de lecture, l’efficacité de la mise en cache conditionne directement la tenue en charge des infrastructures.

REST : Mise en Cache Gratuite sur les CDN Edge

Puisque les opérations de lecture REST exploitent des chemins d’URL distincts via GET, les passerelles mandataires en périphérie (Cloudflare, AWS CloudFront) mettent en cache les réponses sans configuration complexe :

HTTP/1.1 200 OK
Cache-Control: public, max-age=3600, stale-while-revalidate=60
ETag: W/"33a64df551425fcc55e4d42a148795d9f25f89d4"
Content-Type: application/json

Un succès de cache en périphérie réseau est résolu en quelques millisecondes, sans consommer la moindre ressource sur les serveurs ou bases de données applicatives.

GraphQL : Le Défi des Requêtes POST

Les requêtes GraphQL étant majoritairement transmises en HTTP POST vers un unique point d’entrée (/graphql), les serveurs mandataires intermédiaires ne peuvent évaluer la fraîcheur des données sur la seule base de l’URL. Les clients doivent maintenir des magasins normalisés en mémoire (comme Apollo Client) ou exploiter des requêtes persistées automatisées (APQ).


Résoudre le Problème N+1 avec DataLoader

Lors de l’évaluation naïve des résolveurs de champs imbriqués, chaque nœud déclenche une requête SQL distincte vers la base de données (problème N+1). Le patron de conception standard pour neutraliser cette saturation repose sur le regroupement par lot (batching) via DataLoader :

import DataLoader from 'dataloader';
import { db } from './database';

interface Order {
  id: string;
  userId: string;
  total: number;
}

export function createOrderLoader() {
  return new DataLoader<string, Order[]>(async (userIds: readonly string[]) => {
    // Regroupement en une seule requête SQL : SELECT * FROM orders WHERE user_id = ANY($1)
    const orders = await db.query(
      `SELECT * FROM orders WHERE user_id = ANY($1)`,
      [userIds]
    );

    const orderMap = new Map<string, Order[]>();
    for (const userId of userIds) {
      orderMap.set(userId, []);
    }
    for (const order of orders) {
      orderMap.get(order.userId)?.push(order);
    }

    return userIds.map((id) => orderMap.get(id) || []);
  });
}

Matrice de Décision Opérationnelle

Privilégiez REST pour :

  1. Les API Publiques et Écosystèmes Ouverts : Les consommateurs externes disposent de clients HTTP standard sans dépendance envers un écosystème GraphQL dédié.
  2. Les Charges Massives en Lecture Accélérées par CDN : Catalogues de produits, portails d’actualités et contenus médias publics.
  3. Le Transfert de Fichiers Binaires : Téléversement de pièces jointes, diffusion continue de vidéos ou traitement de documents PDF.

Privilégiez GraphQL pour :

  1. La Prise en Charge Multi-Plateforme (Mobile, Web, Objets Connectés) : Chaque terminal bénéficie d’une charge utile minutieusement adaptée à sa bande passante.
  2. Les Tableaux de Bord et Vues Métiers Complexes : Interfaces unifiant les données de dizaines de microservices au sein d’un même écran.
  3. L’Itération Rapide Côté Frontend : Les équipes d’interface peuvent enrichir les vues sans exiger de nouveaux points de terminaison côté backend.

More Engineering Articles