Conception d'API : REST vs GraphQL vs gRPC — Comment choisir
REST, GraphQL et gRPC resoudent chacun un probleme different. Ce guide compare leurs philosophies de conception, compromis et cas d'utilisation ideaux pour vous aider a prendre une decision eclairee pour votre prochaine API.
Toute application moderne communique avec d'autres applications via des API. La question n'est plus de savoir s'il faut construire une API, mais quel style d'API construire. REST est la norme depuis plus d'une decennie. GraphQL a emerge comme une reponse a l'inflexibilite de REST. gRPC adopte une approche completement differente basee sur HTTP/2 et les protocoles buffers. Choisir entre eux necessite de comprendre non seulement la syntaxe, mais aussi la philosophie de conception sous-jacente que chacun represente.
Ce guide decompose chaque protocole d'un point de vue conception : comment vous structurez les ressources ou schemas, comment les clients interagissent avec votre API, comment vous gerez le versioning et la pagination, et comment les exigences temps reel affectent la decision. A la fin, vous aurez un cadre pour choisir le bon outil pour vos contraintes specifiques.
REST : Conception orientee ressource que le web comprend
REST — Representational State Transfer — n'est pas un protocole. C'est un style architectural defini par Roy Fielding dans sa these de doctorat en 2000. L'idee centrale est que vous modelisez votre domaine comme des ressources, chacune identifiee par une URL, et vous manipulez ces ressources via un ensemble uniforme de verbes HTTP : GET, POST, PUT, PATCH et DELETE.
Une bonne conception d'API REST est une conception orientee ressource. Vous ne concevez pas des endpoints autour d'actions - vous concevez des endpoints autour de noms. Au lieu de /createUser ou /getUserById, vous concevez POST /users et GET /users/:id. Cela semble etre une distinction mineure, mais cela affecte profondément la façon dont l'API passe a l'echelle, comment elle est documentee et comment les clients apprennent a l'utiliser.
Un endpoint REST bien conçu pour une ressource utilisateur ressemble a ceci :
GET /users/42
Accept: application/json
Response 200:
{
"id": 42,
"name": "Ada Lovelace",
"email": "ada@example.com",
"role": "admin",
"createdAt": "2025-11-14T09:00:00Z"
}La beaute de REST est sa simplicite. L'URL identifie la ressource, la methode HTTP identifie l'operation et le corps de la reponse contient la representation. Tout client HTTP dans tout langage comprend deja ce contrat. La mise en cache fonctionne immediatement via les en-tetes HTTP. L'outillage comme OpenAPI (anciennement Swagger) vous permet de generer de la documentation, des SDK clients et des stubs serveur a partir d'un seul fichier de schema.
REST rencontre des problemes quand les clients ont besoin de formes differentes de donnees. Un client mobile peut n'avoir besoin que du nom et du role de l'utilisateur, tandis qu'un client tableau de bord a besoin du profil complet avec les donnees d'organisation imbriquees. Avec REST, vous construisez soit plusieurs endpoints, soit forcez chaque client a telecharger la representation complete et a jeter ce dont il n'a pas besoin. C'est le probleme de sur-requete (over-fetching), et c'etait la motivation principale de GraphQL.
GraphQL : Laissez le client decrire exactement ce dont il a besoin
GraphQL, developpe par Meta et publie en 2015, adopte l'approche inverse. Au lieu que le serveur definisse des reponses fixes, le client envoie une requete qui decrit exactement les donnees qu'il veut, et le serveur retourne exactement cette forme. Un seul endpoint, n'importe quelle forme de reponse.
Un schema GraphQL definit les types et les relations dans votre domaine. Le client compose des requetes contre ce schema, ne demandant que les champs dont il a besoin. Le meme concept de ressources imbriquees de REST devient des champs imbriques dans une requete GraphQL, mais le client controle la profondeur et la selection.
// Schema GraphQL (SDL)
type User {
id: ID!
name: String!
email: String!
role: Role!
posts: [Post!]!
}
type Post {
id: ID!
title: String!
body: String!
}
enum Role { USER ADMIN MODERATOR }
type Query {
user(id: ID!): User
}Un client qui a besoin seulement du nom de l'utilisateur et des titres de ses posts envoie une requete qui demande exactement ces champs :
// Requete client
query {
user(id: 42) {
name
posts {
title
}
}
}
// Reponse
{
"data": {
"user": {
"name": "Ada Lovelace",
"posts": [
{ "title": "Notes sur le moteur analytique" }
]
}
}
}Le principe cle de conception dans GraphQL est que le schema est le contrat. Le schema definit ce qui est possible, et le client decide quoi demander parmi les options disponibles. Cela elimine la sur-requete, reduit le nombre de requetes reseau (une seule requete peut remplacer plusieurs allers-retours REST) et donne aux equipes frontend une independance vis-a-vis des changements backend car les nouvelles exigences client ne necessitent pas toujours de nouveaux endpoints.
GraphQL introduit sa propre complexite. La performance des requetes est plus difficile a predire car le client controle ce qui est charge. Le probleme N+1 - ou la resolution de champs imbriques declenche une requete base de donnees independante pour chaque enregistrement parent - necessite des solutions de regroupement comme DataLoader. La mise en cache au niveau HTTP ne fonctionne pas car chaque requete frappe le meme endpoint POST, donc des strategies de mise en cache au niveau application sont necessaires. Et la courbe d'apprentissage pour les resolveurs, mutations, abonnements et types d'entree est plus raide que le modele simple URL-et-verbe de REST.
GraphQL donne aux equipes frontend une independance vis-a-vis des changements backend. Mais cette independance s'accompagne de la responsabilite de comprendre les caracteristiques de performance de chaque requete que votre client envoie au serveur.
gRPC : RPC haute performance base sur HTTP/2 et protobuf
gRPC, developpe a l'origine par Google, adopte encore une autre approche. Au lieu de ressources et de requetes, gRPC modelise les API comme des appels de procedure distante - vous definissez un service avec des methodes, et les clients appellent ces methodes comme s'il s'agissait de fonctions locales. La difference technique cle est que gRPC utilise les Protocol Buffers (protobuf) pour la serialisation au lieu de JSON, et HTTP/2 pour le transport au lieu de HTTP/1.1.
Une definition de service protobuf ne ressemble ni a un endpoint REST ni a un schema GraphQL :
syntax = "proto3";
service UserService {
rpc GetUser (GetUserRequest) returns (User);
rpc ListUsers (ListUsersRequest) returns (ListUsersResponse);
rpc CreateUser (CreateUserRequest) returns (User);
rpc StreamUserUpdates (StreamRequest) returns (stream UserUpdate);
}
message GetUserRequest {
int32 id = 1;
}
message User {
int32 id = 1;
string name = 2;
string email = 3;
Role role = 4;
string created_at = 5;
}
enum Role { ADMIN = 0; USER = 1; }
message StreamRequest {}
message UserUpdate {
User user = 1;
string event_type = 2;
}Protobuf serialise dans un format binaire compact qui est significativement plus petit que JSON et plus rapide a analyser. Combine avec le multiplexage de HTTP/2 - plusieurs flux sur une seule connexion - gRPC atteint une latence considerablement plus faible et un debit plus eleve que REST ou GraphQL pour les communications a volume eleve. Cela fait de gRPC le choix dominant pour les communications entre microservices, ou chaque milliseconde de surcharge de serialisation et chaque octet sur le fil comptent.
gRPC supporte aussi nativement quatre types de streaming : unaire (une requete, une reponse), serveur-streaming (une requete, flux de reponses), client-streaming (flux de requetes, une reponse) et bidirectionnel (les deux cotes diffusent simultanement). Cela en fait l'option la plus forte pour les API temps reel parmi les trois protocoles.
Le compromis est que gRPC est plus difficile a utiliser depuis les navigateurs. Les clients navigateur ne peuvent pas acceder directement aux services gRPC car ils manquent de controle fin sur les trames HTTP/2. gRPC-Web existe comme contournement mais ajoute de la complexite. Les messages Protobuf ne sont pas lisibles par l'homme en transit, ce qui rend le debogage plus difficile - vous avez besoin d'outils comme grpcurl ou un service de reflexion pour inspecter le trafic. Et l'ecosysteme pour la documentation API est moins mature que OpenAPI ou le systeme d'introspection de GraphQL.
Comment ils se comparent sur des aspects pratiques
Choisir entre REST, GraphQL et gRPC est rarement une decision purement technique. Le bon choix depend de qui sont vos clients, de quel type de donnees ils ont besoin et des contraintes de votre reseau et infrastructure. Voici comment chaque protocole se compare sur les aspects pratiques qui comptent le plus en production.
Versioning d'API
REST gere le versioning via l'URL ou l'en-tete Accept. /v1/users et /v2/users peuvent coexister indefiniment, permettant aux clients de migrer a leur rythme. C'est simple et eprouve, mais cela encourage la duplication - l'endpoint v2 duplique souvent la plupart de la logique v1 avec quelques changements. GraphQL evite entierement le versioning en faisant evoluer le schema. Les champs obsoletes sont decores avec une directive @deprecated et restent dans le schema jusqu'a ce que tous les clients aient migre. Cela fonctionne bien quand vous contrôlez tous les clients mais peut creer des frictions dans les API publiques ou les clients se mettent a jour lentement. Le schema protobuf de gRPC est compatible ascendante par conception - vous pouvez ajouter des champs sans casser les clients existants, et les champs obsoletes sont supprimes apres une periode de migration. C'est la strategie de versioning la plus elegante des trois, mais elle necessite de la discipline pour ne jamais renommer ou supprimer un champ sans un cycle d'obsolescence.
Modeles de pagination
La pagination REST se fait typiquement avec une pagination basee sur curseur utilisant un champ nextCursor, ou une pagination basee sur decalage avec les parametres page et limit. Le principe de conception est que la reponse contient un lien ou un jeton suivant, et le client le suit. La pagination GraphQL utilise la spec Relay Connection, qui enveloppe les listes dans des bords avec des curseurs et des informations de page - plus verbeux mais plus cohérent que les approches REST ad-hoc. La pagination gRPC est geree manuellement dans les messages de requete et de reponse, generalement avec un champ page_token et page_size. Il n'y a pas de standard, mais le schema protobuf rend le contrat explicite.
- REST : la pagination basee sur curseur avec nextCursor dans la reponse est le modele recommande pour les API de production
- GraphQL : la spec Relay Connection fournit un modele de pagination standardise avec hasNextPage, hasPreviousPage et des curseurs
- gRPC : la pagination est definie dans vos messages proto ; un modele courant consiste a inclure page_token et page_size dans la requete et next_page_token dans la reponse
Authentification et autorisation
Les trois protocoles reposent sur la meme securite de transport sous-jacente. REST utilise typiquement des jetons Bearer dans l'en-tete Authorization. GraphQL suit le meme modele - puisque toutes les requetes passent par un seul endpoint POST, le jeton est valide au niveau GraphQL ou dans un middleware. gRPC utilise des intercepteurs pour attacher des metadonnees d'authentification a chaque appel, generalement sous forme de jetons JWT transportes dans les en-tetes de metadonnees gRPC. Aucun des trois protocoles ne prescrit de methode d'authentification specifique - le choix entre OAuth2, cles API ou authentification par session est orthogonal au style d'API.
Limitation de taux
La limitation de taux est la plus simple avec REST car chaque endpoint represente une operation bornee. Vous comptez les requetes par endpoint par client et retournez 429 Too Many Requests quand la limite est depassee. GraphQL rend la limitation de taux plus difficile car une seule requete peut declencher des quantites de travail radicalement differentes - une requete pour un champ peut couter une recherche base de donnees, tandis qu'une requete avec des relations profondement imbriquees peut en couter cinquante. Les API GraphQL implementent typiquement une limitation de taux basee sur le cout, ou chaque champ a un poids et le cout total de la requete est calcule avant execution. La limitation de taux gRPC est similaire a REST mais opere au niveau de la methode - vous comptez les appels RPC par methode par client, avec la consideration supplementaire que les appels de streaming consomment des ressources pour leur duree, pas seulement leur initiation.
API temps reel et streaming
REST peut gerer les mises a jour temps reel via WebSockets ou Server-Sent Events (SSE), mais ni l'un ni l'autre ne fait partie de la specification REST - ce sont des protocoles separes ajoutes a cote de l'API HTTP. GraphQL a les abonnements (subscriptions), qui sont une partie de premiere classe de la specification. Un client s'abonne a un evenement et recoit des mises a jour via une connexion WebSocket a chaque occurrence de l'evenement. gRPC a le support temps reel le plus fort avec son streaming bidirectionnel natif sur HTTP/2. Un seul appel gRPC peut diffuser des donnees dans les deux directions simultanement, ce qui est ideal pour les tableaux de bord temps reel, les applications de chat et les systemes pilotes par les evenements. Si la communication temps reel est une exigence principale, le streaming de gRPC est l'option la plus mature et performante, suivi des abonnements GraphQL, puis de REST plus WebSockets.
Documentation et experience developpeur
REST a l'ecosysteme de documentation le plus fort grace a OpenAPI (anciennement Swagger). Une specification OpenAPI decrit chaque endpoint, parametre de requete, schema de reponse et methode d'authentification dans un fichier YAML ou JSON lisible par machine. Des outils comme Swagger UI rendent cela dans une page de documentation interactive, et des generateurs de code produisent des SDK clients pour des dizaines de langages. La maturite de cet ecosysteme signifie qu'un nouveau developpeur peut passer de la lecture d'une spec OpenAPI a son premier appel API reussi en quelques minutes.
GraphQL a l'introspection - un systeme integre ou vous interrogez le schema de l'API via un endpoint special. Des outils comme GraphiQL et Apollo Studio Explorer permettent aux developpeurs de parcourir le schema, d'ecrire des requetes avec auto-completion et de voir la documentation en ligne. C'est une excellente experience pour les developpeurs qui savent deja que votre API existe, mais cela n'aide pas pour la decouverte par les moteurs de recherche ou les places de marche d'API externes comme le fait une spec OpenAPI.
gRPC repose sur les fichiers proto comme source de verite. Le fichier proto est a la fois le schema et la documentation. Des outils comme protoc-gen-doc generent de la documentation de reference a partir des fichiers proto, et la reflexion gRPC permet aux clients de decouvrir les services dynamiquement. L'experience developpeur pour gRPC s'ameliore mais reste en retard sur REST et GraphQL en maturite d'outillage, surtout en dehors de l'ecosysteme des microservices.
Quand utiliser chacun
REST est le bon choix quand votre API est consommee par des developpeurs externes, quand vous avez besoin d'une interoperabilite maximale et quand vos clients ont besoin de la mise en cache HTTP standard. C'est le defaut le plus sur car chaque langage, framework et proxy comprend HTTP. Si vous construisez une API publique, commencez par REST.
GraphQL est le bon choix quand votre API a plusieurs types de clients avec des besoins de donnees differents, quand les equipes frontend doivent pouvoir evoluer independamment des changements backend et quand vous voulez reduire le nombre de requetes reseau. Il excelle dans les applications orientees consommateur avec des clients mobiles et web qui ont besoin de formes differentes des memes donnees.
gRPC est le bon choix pour les communications internes entre microservices, pour les systemes a haut debit ou la surcharge de serialisation compte et pour les applications de streaming temps reel. Si vous construisez un systeme ou les deux extremites sont sous votre controle et que la performance est la preoccupation principale, gRPC est l'option la plus forte.
Aucun de ces protocoles n'est mutuellement exclusif. Une architecture de production courante utilise gRPC pour les communications entre services derriere le pare-feu, expose une passerelle GraphQL qui agrège les donnees de plusieurs services gRPC et fournit une API REST pour les clients externes. La question n'est pas quel protocole utiliser partout - c'est quel protocole utiliser pour chaque interface de votre systeme. Comprendre la philosophie de conception derriere chacun vous donne le jugement pour faire ce choix correctement.
