Client HTTP en TypeScript : techniques avancées de requêtes

Formateur Python en ligne pour débutants

Apprenez Python facilement sans surcharge théorique. Résolvez des tâches pratiques avec vérification automatique et écrivez du code directement dans le navigateur.

Start Course

Client HTTP avancé en TypeScript : des requêtes de base aux solutions industrielles



Lors du développement d'applications web modernes en TypeScript, le travail avec les requêtes HTTP va bien au-delà d'un simple appel à fetch. À un niveau avancé, il ne s'agit pas seulement d'envoyer des requêtes, mais aussi de gérer correctement les erreurs, de contrôler les délais d'attente, de typer les réponses, d'implémenter des intercepteurs et même de mettre en cache les données. Dans cet article, nous allons voir comment construire un client HTTP fiable et flexible en TypeScript, adapté aux projets de production.



1. Création d'un client HTTP typé à l'aide de génériques (Generics)



L'un des principaux avantages de TypeScript est le typage strict. Créons une classe de base HttpClient qui acceptera le type de réponse via des génériques. Cela permettra d'éviter les erreurs à la compilation.



// types.tsexport interface ApiResponse<T> {  data: T;  status: number;  ok: boolean;}

export interface RequestConfig { headers?: Record<string, string>; params?: Record<string, string>; signal?: AbortSignal;}

// http-client.tsimport { ApiResponse, RequestConfig } from './types';

class HttpClient { private baseUrl: string;

constructor(baseUrl: string) { this.baseUrl = baseUrl; }

async get<T>(endpoint: string, config?: RequestConfig): Promise<ApiResponse<T>> { const url = new URL(`${this.baseUrl}${endpoint}`); if (config?.params) { Object.entries(config.params).forEach(([key, value]) => { url.searchParams.append(key, value); }); }

const response = await fetch(url.toString(), { method: 'GET', headers: { 'Content-Type': 'application/json', ...config?.headers, }, signal: config?.signal, });

const data: T = await response.json(); return { data, status: response.status, ok: response.ok, }; }

async post<T, U>(endpoint: string, body: U, config?: RequestConfig): Promise<ApiResponse<T>> { const response = await fetch(`${this.baseUrl}${endpoint}`, { method: 'POST', headers: { 'Content-Type': 'application/json', ...config?.headers, }, body: JSON.stringify(body), signal: config?.signal, });

const data: T = await response.json(); return { data, status: response.status, ok: response.ok }; }}

export default HttpClient;


2. Gestion des erreurs et des délais d'attente



Un client avancé doit gérer correctement à la fois les erreurs réseau et les erreurs de logique métier. Ajoutons un mécanisme de délai d'attente avec AbortController et une gestion personnalisée des erreurs.



// errors.tsexport class HttpError extends Error {  status: number;  data?: unknown;

constructor(message: string, status: number, data?: unknown) { super(message); this.name = 'HttpError'; this.status = status; this.data = data; }}

export class TimeoutError extends Error { constructor(timeout: number) { super(`Requête expirée après ${timeout}ms`); this.name = 'TimeoutError'; }}

// http-client.ts (complément)async requestWithTimeout<T>( endpoint: string, options: RequestInit, timeout: number = 5000): Promise<ApiResponse<T>> { const controller = new AbortController(); const timeoutId = setTimeout(() => controller.abort(), timeout);

try { const response = await fetch(`${this.baseUrl}${endpoint}`, { ...options, signal: controller.signal, });

if (!response.ok) { const errorData = await response.json().catch(() => null); throw new HttpError( `HTTP ${response.status}: ${response.statusText}`, response.status, errorData ); }

const data: T = await response.json(); r

Blogs

Book Recommendations