HTTP-Client in TypeScript: fortgeschrittene Anfragetechniken

Online Python-Trainer für Anfänger

Lernen Sie Python einfach ohne theoretische Überlastung. Lösen Sie praktische Aufgaben mit automatischer Überprüfung und schreiben Sie Code direkt im Browser.

Kurs starten

Fortgeschrittener HTTP-Client in TypeScript: Von einfachen Anfragen zu industriellen Lösungen



Bei der Entwicklung moderner Webanwendungen in TypeScript geht die Arbeit mit HTTP-Anfragen weit über einen einfachen Aufruf von fetch hinaus. Auf fortgeschrittenem Niveau ist es nicht nur erforderlich, Anfragen zu senden, sondern auch Fehler korrekt zu behandeln, Timeouts zu verwalten, Antworten zu typisieren, Interceptors zu implementieren und sogar Daten zwischenzuspeichern. In diesem Artikel werden wir erläutern, wie man einen zuverlässigen und flexiblen HTTP-Client in TypeScript erstellt, der für Produktionsprojekte geeignet ist.



1. Erstellung eines typisierten HTTP-Clients mit Generics



Einer der Hauptvorteile von TypeScript ist die strenge Typisierung. Erstellen wir eine Basisklasse HttpClient, die den Antworttyp über Generics akzeptiert. Dies hilft, Fehler bereits zur Kompilierungszeit zu vermeiden.



// 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. Fehlerbehandlung und Timeouts



Ein fortgeschrittener Client sollte sowohl Netzwerkfehler als auch Fehler der Geschäftslogik korrekt behandeln. Fügen wir einen Timeout-Mechanismus mit AbortController und eine benutzerdefinierte Fehlerbehandlung hinzu.



// 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(`Anfrage nach ${timeout}ms abgelaufen`); this.name = 'TimeoutError'; }}

// http-client.ts (Erweiterung)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

Buchempfehlungen