API REST vs GraphQL : Quel choix pour votre projet en 2025 ?
Comparatif complet entre API REST et GraphQL en 2025 : principes, avantages, inconvénients, performances, cas d'usage et exemples de code concrets pour Node.js/Express et Apollo Server.
Introduction : REST ou GraphQL, le grand débat de 2025
En 2025, le choix entre REST (Representational State Transfer) et GraphQL reste l'une des décisions architecturales les plus importantes lors de la conception d'une API. REST, créé en 2000, est le standard historique utilisé par des millions d'applications. GraphQL, introduit par Facebook en 2015, promet une alternative plus flexible et efficace.
Mais lequel choisir pour votre projet ? Ce guide complet vous aide à comprendre les forces et faiblesses de chaque approche, avec des exemples concrets et des recommandations basées sur vos besoins réels.
Qu'est-ce qu'une API REST ?
REST (Representational State Transfer) est un style d'architecture basé sur le protocole HTTP. Une API REST expose des ressources (users, posts, products...) accessibles via des endpoints utilisant les méthodes HTTP standard.
Principes fondamentaux de REST
- Ressources identifiées par URL :
/users/123,/posts/456 - Méthodes HTTP : GET (lecture), POST (création), PUT/PATCH (modification), DELETE (suppression)
- Stateless : chaque requête contient toutes les informations nécessaires
- Cacheable : les réponses peuvent être mises en cache (HTTP headers)
- Uniform Interface : interface standardisée et prévisible
Exemple d'API REST
// Récupérer un utilisateur
GET /api/users/123
// Créer un article
POST /api/posts
Body: { "title": "Mon article", "content": "..." }
// Mettre à jour un utilisateur
PATCH /api/users/123
Body: { "email": "newemail@example.com" }
// Supprimer un article
DELETE /api/posts/456Qu'est-ce que GraphQL ?
GraphQL est un langage de requête pour API développé par Facebook en 2012 et open-sourcé en 2015. Contrairement à REST, GraphQL expose un point d'entrée unique et permet au client de spécifier exactement les données dont il a besoin.
Principes fondamentaux de GraphQL
- Un seul endpoint : généralement
/graphql - Schema fortement typé : définit types, queries, mutations
- Client demande ce qu'il veut : pas d'overfetching ni underfetching
- Introspection : le schema est auto-documenté
- Résolution de requêtes complexes : relations imbriquées en une seule requête
Exemple de requête GraphQL
// Récupérer un utilisateur avec ses posts et commentaires
query {
user(id: "123") {
name
email
posts {
title
comments {
content
author {
name
}
}
}
}
}Cette requête renvoie exactement les champs demandés, avec toutes les relations, en une seule requête HTTP.
Comparaison approfondie : REST vs GraphQL
1. Structure et endpoints
| Aspect | REST | GraphQL |
|---|---|---|
| Endpoints | Multiple (un par ressource) | Un seul (/graphql) |
| Structure | Basé sur ressources | Basé sur schema |
| Documentation | Swagger/OpenAPI (externe) | Introspection native |
Exemple REST :
GET /api/users // Liste des utilisateurs
GET /api/users/123 // Un utilisateur
GET /api/users/123/posts // Posts d'un utilisateur
GET /api/posts/456/comments // Commentaires d'un postExemple GraphQL :
POST /graphql
Body: { "query": "{ users { id name } }" }2. Overfetching et Underfetching
Problème d'Overfetching (REST)
Avec REST, l'endpoint renvoie souvent plus de données que nécessaire.
// Je veux juste le nom et l'email
GET /api/users/123
// Mais je reçois TOUT :
{
"id": 123,
"name": "John",
"email": "john@example.com",
"phone": "+33...",
"address": { ... },
"preferences": { ... },
"createdAt": "...",
"updatedAt": "..."
}➡️ Gaspillage de bande passante (surtout mobile)
Problème d'Underfetching (REST)
Parfois, il faut plusieurs requêtes pour obtenir toutes les données nécessaires.
// 1. Récupérer l'utilisateur
GET /api/users/123
// 2. Récupérer ses posts
GET /api/users/123/posts
// 3. Pour chaque post, récupérer les commentaires
GET /api/posts/1/comments
GET /api/posts/2/comments
GET /api/posts/3/comments
// = 5+ requêtes HTTP➡️ Problème N+1 : latence élevée
Solution GraphQL
// Une seule requête pour tout
query {
user(id: "123") {
name
email
posts {
title
comments {
content
}
}
}
}
// ✅ Exactement les champs demandés
// ✅ Une seule requête HTTP3. Versioning
| Aspect | REST | GraphQL |
|---|---|---|
| Versioning | Nécessaire (/api/v1/, /api/v2/) | Pas de versioning (deprecated fields) |
| Breaking changes | Nouvelle version de l'API | Marquer champ comme @deprecated |
REST : quand vous changez la structure, vous créez une nouvelle version.
// Ancienne API
GET /api/v1/users → { "name": "John Doe" }
// Nouvelle API (breaking change)
GET /api/v2/users → { "firstName": "John", "lastName": "Doe" }GraphQL : vous ajoutez de nouveaux champs sans casser l'ancien.
type User {
name: String @deprecated(reason: "Use firstName and lastName")
firstName: String
lastName: String
}4. Caching
| Aspect | REST | GraphQL |
|---|---|---|
| Caching HTTP | ✅ Natif (GET cacheable) | ❌ POST non cacheable par défaut |
| Caching applicatif | Redis, Memcached | Apollo Client, Relay (côté client) |
REST : cache HTTP standard (ETag, Cache-Control)
GET /api/users/123
Cache-Control: max-age=3600
ETag: "abc123"GraphQL : nécessite caching applicatif (Apollo Client, DataLoader)
// Apollo Client cache automatiquement par ID
const { data } = useQuery(GET_USER, {
variables: { id: "123" },
fetchPolicy: "cache-first"
});5. Performances
| Scénario | REST | GraphQL |
|---|---|---|
| Requête simple | ✅ Rapide | ⚠️ Légèrement plus lent (parsing) |
| Données imbriquées | ❌ Plusieurs requêtes (lent) | ✅ Une requête (rapide) |
| Mobile/3G | ❌ Overfetching = bande passante | ✅ Données précises |
6. Sécurité
| Risque | REST | GraphQL |
|---|---|---|
| Rate limiting | ✅ Par endpoint | ⚠️ Complexe (par query depth) |
| Attaques DOS | ✅ Limité par endpoint | ❌ Requêtes complexes imbriquées |
| Autorisation | ✅ Par route | ⚠️ Par champ (plus granulaire mais complexe) |
Problème GraphQL : requêtes malveillantes
// Requête qui peut tuer le serveur
query {
users {
posts {
comments {
author {
posts {
comments {
author {
# ... infiniment imbriqué
}
}
}
}
}
}
}
}➡️ Solutions : query depth limit, query complexity limit, persistent queries
Exemples de code : Implémentation
API REST avec Express (Node.js)
// server.js
const express = require('express');
const app = express();
app.use(express.json());
// GET /users
app.get('/users', async (req, res) => {
const users = await db.query('SELECT * FROM users');
res.json(users);
});
// GET /users/:id
app.get('/users/:id', async (req, res) => {
const user = await db.query('SELECT * FROM users WHERE id = ?', [req.params.id]);
if (!user) return res.status(404).json({ error: 'User not found' });
res.json(user);
});
// POST /users
app.post('/users', async (req, res) => {
const { name, email } = req.body;
const result = await db.query('INSERT INTO users (name, email) VALUES (?, ?)', [name, email]);
res.status(201).json({ id: result.insertId, name, email });
});
// PUT /users/:id
app.put('/users/:id', async (req, res) => {
const { name, email } = req.body;
await db.query('UPDATE users SET name = ?, email = ? WHERE id = ?', [name, email, req.params.id]);
res.json({ id: req.params.id, name, email });
});
// DELETE /users/:id
app.delete('/users/:id', async (req, res) => {
await db.query('DELETE FROM users WHERE id = ?', [req.params.id]);
res.status(204).send();
});
app.listen(3000, () => console.log('REST API sur port 3000'));API GraphQL avec Apollo Server
// server.js
const { ApolloServer, gql } = require('apollo-server');
// 1. Définir le schema
const typeDefs = gql`
type User {
id: ID!
name: String!
email: String!
posts: [Post!]!
}
type Post {
id: ID!
title: String!
content: String!
author: User!
comments: [Comment!]!
}
type Comment {
id: ID!
content: String!
author: User!
}
type Query {
users: [User!]!
user(id: ID!): User
posts: [Post!]!
}
type Mutation {
createUser(name: String!, email: String!): User!
createPost(title: String!, content: String!, authorId: ID!): Post!
}
`;
// 2. Définir les resolvers
const resolvers = {
Query: {
users: () => db.query('SELECT * FROM users'),
user: (_, { id }) => db.query('SELECT * FROM users WHERE id = ?', [id]),
posts: () => db.query('SELECT * FROM posts'),
},
Mutation: {
createUser: async (_, { name, email }) => {
const result = await db.query('INSERT INTO users (name, email) VALUES (?, ?)', [name, email]);
return { id: result.insertId, name, email };
},
createPost: async (_, { title, content, authorId }) => {
const result = await db.query('INSERT INTO posts (title, content, author_id) VALUES (?, ?, ?)',
[title, content, authorId]);
return { id: result.insertId, title, content, authorId };
},
},
User: {
posts: (user) => db.query('SELECT * FROM posts WHERE author_id = ?', [user.id]),
},
Post: {
author: (post) => db.query('SELECT * FROM users WHERE id = ?', [post.author_id]),
comments: (post) => db.query('SELECT * FROM comments WHERE post_id = ?', [post.id]),
},
Comment: {
author: (comment) => db.query('SELECT * FROM users WHERE id = ?', [comment.author_id]),
},
};
// 3. Créer le serveur
const server = new ApolloServer({ typeDefs, resolvers });
server.listen(4000).then(({ url }) => {
console.log(`GraphQL API sur ${url}`);
});Cas d'usage : Quand utiliser REST ou GraphQL ?
✅ Utilisez REST si :
- API publique simple : CRUD basique, peu de relations complexes
- Caching HTTP important : CDN, cache navigateur essentiel
- Équipe peu expérimentée : REST est plus simple à comprendre
- Microservices : communication inter-services (REST/gRPC)
- Standards requis : certains secteurs exigent REST
- Rate limiting simple : par endpoint
Exemples :
- API de paiement (Stripe-like)
- API météo
- API de géolocalisation
- Webhook endpoints
✅ Utilisez GraphQL si :
- Données fortement relationnelles : relations complexes (réseaux sociaux, e-commerce)
- Multiples clients : web, mobile, IoT avec besoins différents
- Développement rapide : évolution fréquente du frontend
- Optimisation mobile : réduire la bande passante
- Agrégation de données : fusionner plusieurs sources
- Real-time : subscriptions GraphQL pour WebSocket
Exemples :
- Réseaux sociaux (Facebook, Instagram, Twitter)
- Dashboard analytics (données multiples sources)
- E-commerce (produits + avis + stock + recommandations)
- SaaS complexe (Notion-like, Linear-like)
Tableau récapitulatif : REST vs GraphQL
| Critère | REST | GraphQL | Gagnant |
|---|---|---|---|
| Simplicité | ✅ Simple | ⚠️ Courbe d'apprentissage | REST |
| Flexibilité client | ❌ Rigide | ✅ Très flexible | GraphQL |
| Overfetching | ❌ Problème | ✅ Résolu | GraphQL |
| Underfetching | ❌ Problème (N+1) | ✅ Résolu | GraphQL |
| Caching HTTP | ✅ Natif | ❌ Complexe | REST |
| Versioning | ❌ Nécessaire | ✅ Pas besoin | GraphQL |
| Rate limiting | ✅ Simple | ❌ Complexe | REST |
| Documentation | ⚠️ Externe (Swagger) | ✅ Auto-générée | GraphQL |
| Tooling | ✅ Mature (Postman, etc.) | ✅ Excellent (GraphQL Playground) | Égalité |
| Adoption | ✅ Universelle | ⚠️ Croissante | REST |
Hybride : Peut-on utiliser les deux ?
Oui ! De nombreuses entreprises utilisent les deux :
- REST pour les endpoints publics simples (webhooks, auth)
- GraphQL pour les applications clientes riches (dashboard, mobile app)
Exemple : GitHub
- API REST v3 :
https://api.github.com/users/octocat - API GraphQL v4 :
https://api.github.com/graphql
Tendances 2025
- REST reste majoritaire : 70% des APIs publiques
- GraphQL en forte croissance : +40% adoption depuis 2020
- tRPC émerge : alternative TypeScript-native pour full-stack apps
- gRPC pour microservices : plus rapide que REST/GraphQL
Conclusion : Quel choix faire en 2025 ?
Il n'y a pas de réponse universelle. Voici la recommandation selon votre contexte :
Choisissez REST si :
- ✅ Vous débutez ou avez une équipe junior
- ✅ API publique simple (CRUD basique)
- ✅ Caching HTTP critique (CDN, edge caching)
- ✅ Microservices avec communication simple
Choisissez GraphQL si :
- ✅ Données fortement relationnelles (réseaux sociaux, CMS)
- ✅ Multiples clients avec besoins différents (web + mobile + IoT)
- ✅ Optimisation bande passante critique (mobile, IoT)
- ✅ Développement rapide avec itérations fréquentes
Utilisez les deux si :
- ✅ Grande application avec besoins variés
- ✅ Migration progressive (REST → GraphQL)
- ✅ API publique (REST) + dashboard interne (GraphQL)
En 2025, GraphQL est mature et production-ready. Des géants comme Facebook, Twitter, GitHub, Shopify, Netflix l'utilisent massivement. Mais REST reste pertinent pour de nombreux cas d'usage et ne va pas disparaître.
Commencez simple (REST), migrez vers GraphQL si le besoin émerge. 🚀