Cliente HTTP em TypeScript: fazendo requisições corretamente

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course

Cliente HTTP em TypeScript: fazendo requisições corretamente



No desenvolvimento web moderno, trabalhar com requisições HTTP é uma das tarefas principais. TypeScript, como uma extensão estritamente tipada sobre JavaScript, fornece aos desenvolvedores ferramentas poderosas para criar clientes HTTP confiáveis e previsíveis. Neste artigo, vamos analisar como organizar corretamente um cliente HTTP em TypeScript para que seu código seja seguro, legível e facilmente mantível.



Por que TypeScript é ideal para clientes HTTP?



TypeScript adiciona tipagem estática, o que é especialmente importante ao trabalhar com APIs externas. Você sabe exatamente quais dados virão do servidor e pode prevenir muitos erros em tempo de compilação. Vejamos um exemplo básico:



// Ruim: JavaScript sem tiposconst data = await fetch('/api/users');const users = await data.json();// Não sabemos a estrutura de users

// Bom: TypeScript com tiposinterface User { id: number; name: string; email: string;}

const response = await fetch('/api/users');const users: User[] = await response.json();// Agora users tem uma estrutura clara


Criando um cliente HTTP básico em TypeScript



Vamos começar criando um cliente HTTP universal que lidará com todos os tipos de requisições. Usaremos a API nativa fetch, disponível em navegadores modernos e Node.js 18+.



Implementação básica com tipagem



interface HttpClientConfig {  baseURL: string;  headers?: Record<string, string>;  timeout?: number;}

interface ApiResponse<T> { data: T; status: number; ok: boolean;}

class HttpClient { private baseURL: string; private headers: Record<string, string>; private timeout: number;

constructor(config: HttpClientConfig) { this.baseURL = config.baseURL; this.headers = { 'Content-Type': 'application/json', ...config.headers, }; this.timeout = config.timeout || 10000; }

private async request<T>( endpoint: string, options: RequestInit = {} ): Promise<ApiResponse<T>> { const url = `${this.baseURL}${endpoint}`; const controller = new AbortController(); const timeoutId = setTimeout(() => controller.abort(), this.timeout);

try { const response = await fetch(url, { ...options, headers: { ...this.headers, ...options.headers }, signal: controller.signal, });

clearTimeout(timeoutId);

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

return { data, status: response.status, ok: response.ok, }; } catch (error) { clearTimeout(timeoutId); throw this.handleError(error); } }

private handleError(error: unknown): Error { if (error instanceof DOMException && error.name === 'AbortError') { return new Error('Request timeout'); } if (error instanceof TypeError) { return new Error('Network error'); } return error as Error; }

async get<T>(endpoint: string): Promise<ApiResponse<T>> { return this.request<T>(endpoint, { method: 'GET' }); }

async post<T>(endpoint: string, body: unknown): Promise<ApiResponse<T>> { return this.request<T>(endpoint, { method: 'POST', body: JSON.stringify(body), }); }

async put<T>(endpoint: string, body: unknown): Promise<ApiResponse<T>> { return this.request<T>(endpoint, { method: 'PUT', body: JSON.stringify(body), }); }

async delete<T>(endpoint: string): Promise<ApiResponse<T>> { return this.request<T>(endpoint, { method: 'DELETE' }); }}


Usando o cliente



// Criando uma instância do clienteconst api = new HttpClient({  baseURL: 'https://api.                

Blogs

Book Recommendations