Paradigmes d’API : REST vs GraphQL vs tRPC pour les Stacks TypeScript
Vitesse de développement, compilation de schémas client et mise en cache réseau.
1. Typage de bout en bout sans génération de code
L’idée centrale de tRPC est que, si votre client et votre serveur vivent dans le même monorepo TypeScript, vous n’avez besoin ni d’un langage de définition de schéma, ni d’une étape de génération de code, ni d’une couche de validation de types au runtime — le compilateur TypeScript lui-même peut servir de contrat. Un routeur tRPC exporte les types de ses procédures, le client importe ce type (jamais l’implémentation), et appeler `trpc.user.getById.query({ id })` est typé de bout en bout, y compris l’inférence des champs optionnels, des unions discriminées et des formes validées par Zod.
Cela élimine toute une catégorie de bugs de dérive : le cas classique où le backend renomme un champ, la spec OpenAPI se régénère, mais l’appel fetch écrit à la main côté frontend référence encore l’ancien nom de champ et échoue silencieusement à l’exécution. Avec tRPC, ce renommage devient une erreur de compilation côté frontend dès l’enregistrement du fichier, avant même de lancer l’application. Pour une petite équipe qui livre vite dans un seul dépôt, ce retour immédiat vaut plus que presque tout autre investissement en outillage d’API.
Le piège, c’est l’exigence de monorepo. L’inférence de types de tRPC ne fonctionne que parce que le client peut littéralement importer les types TypeScript du serveur au moment du build. Si votre équipe mobile, vos consommateurs d’API publique ou une intégration partenaire ont besoin du même backend, vous revenez à la nécessité d’un schéma indépendant du langage — ce que tRPC ne fournit volontairement pas. C’est un protocole pour outils internes et clients de première partie, pas un protocole d’interopérabilité.
2. Quand utiliser GraphQL ?
GraphQL résout un problème précis que ni REST ni tRPC n’adressent bien : la sélection de champs pilotée par le client, sur un graphe profondément imbriqué et détenu par le produit, consommé par plusieurs frontends indépendants. Une app mobile, un dashboard web et une intégration tierce peuvent chacun demander exactement les champs dont ils ont besoin sur le même type `Post` — le client mobile ignore le fil de commentaires complet, le dashboard demande des compteurs agrégés — sans que l’équipe backend maintienne N endpoints sur mesure, ni qu’un client transporte un payload inutilisé.
Cela compte surtout dans les organisations où les équipes frontend et backend sont organisationnellement séparées et itèrent indépendamment. Un schéma GraphQL publié est un véritable contrat qui survit aux frontières d’équipe d’une façon que l’inférence à la compilation de tRPC ne peut pas offrir, car GraphQL est indépendant du langage et n’exige pas que le consommateur partage le système de build du producteur. Des outils comme GraphQL Code Generator récupèrent une bonne partie du bénéfice de sécurité de typage de tRPC pour les clients TypeScript spécifiquement, en générant des hooks typés à partir de fichiers d’opérations `.graphql` contre le schéma publié.

