Introduction : une API n'est pas qu'une question de requêtes, c'est un dialogue
Il fut un temps, à l'ère des monolithes, où les développeurs écrivaient le backend en PHP ou Java, et le frontend se contentait d'appeler des URL toutes faites. Tout était simple, mais lent. Aujourd'hui, l'écosystème TypeScript dicte de nouvelles règles : nous ne voulons pas seulement échanger des données, mais le faire de manière sécurisée, stricte et avec l'auto-complétion. C'est ici qu'entrent en jeu les trois géants : REST, GraphQL et gRPC.
Dans cet article, nous ne nous contenterons pas de répéter la documentation. Nous passerons en revue chaque protocole du point de vue d'un praticien TypeScript : nous verrons des exemples de code concrets, comparerons les performances et comprendrons quel outil convient à votre projet. Si vous codez en TypeScript et souhaitez améliorer vos compétences en matière d'API, vous êtes au bon endroit.
API REST en TypeScript : un classique qui ne meurt pas
REST (Representational State Transfer) est le standard de facto. Simplicité, méthodes HTTP (GET, POST, PUT, DELETE) et ressources. Mais en TypeScript, REST se révèle sous un nouveau jour : nous obtenons un typage strict des requêtes et des réponses.
À quoi ressemble un client REST typé
Écrivons un client minimal mais fonctionnel pour une API REST en TypeScript. Sans bibliothèques superflues — seulement fetch et des types.
// Types pour la réponseinterface User { id: number; name: string; email: string;}
interface ApiResponse<T> { data: T; status: number; message: string;}
// Client typéclass RestClient { private baseUrl: string;
constructor(baseUrl: string) { this.baseUrl = baseUrl; }
async get<T>(endpoint: string): Promise<ApiResponse<T>> { const response = await fetch(`${this.baseUrl}${endpoint}`, { method: 'GET', headers: { 'Content-Type': 'application/json' }, });
if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); }
const data: T = await response.json(); return { data, status: response.status, message: 'Success', }; }
async post<T, U>(endpoint: string, body: U): Promise<ApiResponse<T>> { const response = await fetch(`${this.baseUrl}${endpoint}`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(body), });
if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); }
const data: T = await response.json(); return { data, status: response.status, message: 'Created', }; }}
// Utilisationconst client = new RestClient('https://jsonplaceholder.typicode.com');
async function fetchUser() { const response = await client.get<User>('/users/1'); console.log(response.data.name); // L'auto-complétion fonctionne !}
fetchUser();Comme vous le voyez, l'API REST TypeScript nous donne le contrôle sur les types à chaque étape. Une erreur dans le nom d'un champ ? TypeScript la détectera à la compilation.
Quand choisir REST
- Simplicité — REST est facile à comprendre et à maintenir.
- Mise en cache — le cache HTTP fonctionne nativement.
- Applications CRUD — blogs, boutiques, panneaux d'administration.
Inconvénient : pour les requêtes imbriquées complexes, vous obtenez soit beaucoup de données (sur-récupération), soit vous effectuez N requêtes (problème N+1).
GraphQL en TypeScript : flexibilité et précision
GraphQL est un langage de requêtes créé par Facebook. Son principal atout : vous décidez vous-même quels champs obtenir. GraphQL TypeScript est un tandem puissant qui offre une sécurité de typage totale côté client et serveur.
Écrire une requête GraphQL avec typage
Pour l'exemple, utilisons la bibliothèque graphql-request — un client léger pour TypeScript.
import { request, gql } from 'grap