Cliente HTTP em TypeScript: fazendo requisições corretamente: do A ao Z

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



TypeScript é uma extensão fortemente tipada do JavaScript que adiciona confiabilidade e legibilidade ao código no desenvolvimento web. Ao trabalhar com APIs externas ou backend, a habilidade de executar requisições HTTP corretamente torna-se essencial. Neste artigo, vamos abordar como criar um cliente HTTP completo em TypeScript, desde os princípios básicos até padrões avançados de tratamento de erros e tipagem.



Por que TypeScript é ideal para clientes HTTP?



JavaScript oferece várias formas de executar requisições HTTP: o nativo fetch, as bibliotecas axios e node-fetch. No entanto, o TypeScript permite elevar o trabalho com elas a um novo nível graças à tipagem estática. Você pode descrever antecipadamente a estrutura da requisição e da resposta, eliminando muitos erros em tempo de compilação. Imagine que você está trabalhando com uma API que retorna uma lista de usuários. Sem tipos, você corre o risco de acessar um campo inexistente, e o erro só aparecerá em tempo de execução. O TypeScript resolve esse problema.



Parte principal: criando um cliente HTTP do zero



1. Requisição GET básica com fetch e tipagem



Vamos começar com o mais simples — uma requisição GET. No TypeScript, podemos definir uma interface para a resposta e passá-la para a função genérica fetch. Veja o exemplo:



interface User {  id: number;  name: string;  email: string;}

async function getUser(id: number): Promise<User> { const response = await fetch(`https://jsonplaceholder.typicode.com/users/${id}`); if (!response.ok) { throw new Error(`Erro HTTP! status: ${response.status}`); } const data: User = await response.json(); return data;}

// UsogetUser(1) .then(user => console.log(user.name)) .catch(error => console.error('Erro:', error.message));


Aqui, indicamos explicitamente que a função retorna Promise<User>. Se a API mudar, o compilador TypeScript avisará sobre a incompatibilidade de tipos. Observe a verificação de response.ok — este é um passo obrigatório para tratar erros HTTP (404, 500, etc.).



2. Requisição POST com corpo e cabeçalhos



Enviar dados para o servidor requer configuração de cabeçalhos e serialização do corpo da requisição. Vamos criar uma função para adicionar um novo usuário:



interface CreateUserRequest {  name: string;  email: string;}

interface CreateUserResponse { id: number; name: string; email: string;}

async function createUser(userData: CreateUserRequest): Promise<CreateUserResponse> { const response = await fetch('https://jsonplaceholder.typicode.com/users', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify(userData), });

if (!response.ok) { const errorBody = await response.text(); throw new Error(`Erro ao criar: ${response.status} - ${errorBody}`); }

return await response.json();}

// Exemplo de chamadaconst newUser: CreateUserRequest = { name: 'João', email: 'joao@example.com' };createUser(newUser).then(result => console.log('ID criado:', result.id));


A tipagem de CreateUserRequest e CreateUserResponse torna o código autodocumentado. Outros desenvolvedores veem imediatamente quais campos são obrigatórios para envio e o que esperar na resposta.



3. Cliente HTTP universal com tratamento de erros



Em projetos reais, raramente se usa apenas uma função. É melhor criar uma classe ou conjunto de funções universais que centralizem a lógica das requisições. Veja um exemplo de cliente avançado:



type HttpMethod = 'GET' | 'POST' | 'PUT' | 'DELETE';

interface RequestConfig { method: HttpMethod; endpoint: string; body?: unknown; params?: Record<string, string>;}

class HttpClient { private baseUrl: string;\

Blogs

Book Recommendations