SOAP, REST, GraphQL : choisir le bon protocole d'API
Trois façons d'exposer des données sur le réseau, trois philosophies différentes. Comprendre les vraies différences pour faire le bon choix.
Trois protocoles d'API, trois façons de penser la communication entre systèmes. SOAP date de 1998 et tourne encore dans des milliers de systèmes bancaires. REST a dominé les années 2010. GraphQL bouleverse les architectures frontend depuis 2015. Aucun n'est mort, aucun n'est universellement supérieur.
SOAP — quand le contrat prime sur tout
SOAP (Simple Object Access Protocol) n'est pas un protocole HTTP au sens habituel. C'est un protocole de messaging basé sur XML, qui peut tourner sur HTTP, SMTP, ou TCP. Chaque requête est une enveloppe XML envoyée en POST, peu importe l'opération.
POST /banking/service HTTP/1.1
Content-Type: text/xml; charset=utf-8
SOAPAction: "getAccountBalance"
<?xml version="1.0"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
<auth:Token xmlns:auth="http://mybank.com/auth">
eyJhbGc...
</auth:Token>
</soap:Header>
<soap:Body>
<m:GetBalance xmlns:m="http://mybank.com/accounts">
<m:AccountId>FR76-1234-5678</m:AccountId>
</m:GetBalance>
</soap:Body>
</soap:Envelope>Ce qui distingue SOAP, c'est le WSDL (Web Services Description Language) — un fichier XML qui décrit exhaustivement le service : toutes les opérations disponibles, les types de chaque paramètre, les erreurs possibles. Le WSDL est un contrat machine-readable. Votre outil génère les stubs client automatiquement depuis ce fichier.
<!-- Extrait WSDL -->
<wsdl:operation name="GetBalance">
<wsdl:input message="tns:GetBalanceRequest"/>
<wsdl:output message="tns:GetBalanceResponse"/>
<wsdl:fault message="tns:AccountNotFoundFault"/>
</wsdl:operation>SOAP supporte aussi les standards WS-* : WS-Security (chiffrement, signatures), WS-Transactions (transactions distribuées), WS-ReliableMessaging (garanties de livraison). Des fonctionnalités que REST n'a pas nativement.
Quand choisir SOAP : intégration avec des systèmes legacy (banques, assurances, ERP SAP), contrats d'interopérabilité stricts entre entreprises, transactions distribuées nécessitant des garanties ACID.
REST — l'HTTP tel qu'il était conçu
REST (Representational State Transfer) n'est pas un protocole mais un style architectural, défini par Roy Fielding en 2000. L'idée centrale : les ressources sont des URLs, les verbes HTTP (GET, POST, PUT, DELETE, PATCH) définissent les opérations.
GET /users/42 → récupérer l'utilisateur 42
POST /users → créer un utilisateur
PUT /users/42 → remplacer complètement l'utilisateur 42
PATCH /users/42 → modifier partiellement l'utilisateur 42
DELETE /users/42 → supprimer l'utilisateur 42
GET /users/42/orders → commandes de l'utilisateur 42REST exploite tout ce que HTTP offre : codes de statut (200, 201, 404, 422), headers (Authorization, Cache-Control, ETag), content negotiation (JSON, XML, MessagePack via Accept). Les réponses sont cachées par défaut par les proxies et CDN — un avantage de performance immédiat.
# Exemple REST avec curl
curl -X POST https://api.example.com/users \
-H "Authorization: Bearer eyJhbG..." \
-H "Content-Type: application/json" \
-d '{"name": "Alice", "email": "alice@example.com"}'
# 201 Created
# Location: /users/42Le problème classique de REST : over-fetching et under-fetching. Pour afficher une liste d'articles avec leurs auteurs et le nombre de commentaires, vous faites potentiellement trois requêtes séparées ou vous créez un endpoint /articles?include=author,commentCount ad hoc. La rigidité des endpoints REST suit le rythme des besoins frontend.
Quand choisir REST : APIs publiques exposées à des tiers, services où le caching HTTP est critique (CDN, proxies), architectures microservices avec communication inter-services simple, cas où la simplicité l'emporte.
GraphQL — le client aux commandes
GraphQL est un langage de requête pour vos APIs. Un seul endpoint (/graphql), et le client décrit exactement les données qu'il veut.
# Le client demande exactement ce dont il a besoin
query {
articles(first: 10) {
id
title
author {
name
avatar
}
_count {
comments
}
}
}Le serveur retourne exactement ça — ni plus, ni moins. Fini l'over-fetching d'une réponse REST de 40 champs quand vous en avez besoin de 5. Fini l'under-fetching qui force 3 requêtes pour construire un écran.
GraphQL a un schéma fortement typé, introspectable :
type Article {
id: ID!
title: String!
content: String!
author: User!
comments: [Comment!]!
createdAt: DateTime!
}
type Query {
articles(first: Int, after: String): ArticleConnection!
article(id: ID!): Article
}
type Mutation {
createArticle(input: CreateArticleInput!): Article!
deleteArticle(id: ID!): Boolean!
}L'introspection permet aux outils comme GraphiQL ou Postman de vous proposer l'autocomplétion — exactement comme le WSDL de SOAP, mais plus ergonomique.
Les Subscriptions GraphQL ajoutent le temps réel via WebSocket :
subscription {
commentAdded(articleId: "42") {
id
content
author { name }
}
}Quand choisir GraphQL : applications avec des clients multiples (web, mobile, tablette) aux besoins différents, données fortement relationnelles, équipes frontend qui veulent l'autonomie sur les données qu'elles consomment, évolution fréquente du schema de données.
Comparaison directe
| Critère | SOAP | REST | GraphQL |
|---|---|---|---|
| Format | XML | JSON / autre | JSON |
| Endpoints | 1 par opération | 1 par ressource | 1 seul |
| Contrat | WSDL strict | OpenAPI (optionnel) | Schéma introspectable |
| Caching | Difficile | Natif HTTP | Complexe |
| Over/under-fetching | Oui | Oui | Non |
| Temps réel | WS-* | SSE / polling | Subscriptions |
| Courbe d'apprentissage | Élevée | Faible | Moyenne |
| Idéal pour | Enterprise legacy | APIs publiques | Apps modernes |
Les pièges de chaque approche
SOAP : verbosité XML, tooling lourd, debugging pénible. Une erreur de namespace dans l'enveloppe et la requête est rejetée silencieusement. Pas adapté aux clients JavaScript modernes.
REST : les endpoints prolifèrent avec les besoins. Une API REST bien conçue demande de la discipline — versionning (/v1/, /v2/), cohérence des noms, gestion des erreurs standardisée. Beaucoup d'APIs REST en production sont en réalité du HTTP avec du JSON sans vraiment respecter les contraintes REST.
GraphQL : le caching HTTP traditionnel ne fonctionne pas (toutes les requêtes sont POST sur le même endpoint). Le problème N+1 des resolvers doit être géré avec DataLoader. La complexité des requêtes peut exposer le serveur à des attaques de déni de service par requêtes arbitrairement profondes.
SOAP survit dans les systèmes qui ne peuvent pas changer. REST reste le choix par défaut pour une API que des tiers vont consommer. GraphQL s'impose dès que le frontend a des besoins complexes et variables. Dans une même architecture, avoir REST pour l'API publique et GraphQL pour le backend-for-frontend est une combinaison courante.
Pour aller plus loin sur la sécurité de ces APIs — authentification, rate limiting, validation — sécuriser une API REST couvre les patterns incontournables.
Si vous construisez en Go, créer une API REST en Go montre comment implémenter les patterns REST avec le standard library.