JavaScript Fetch API
A Fetch API é uma interface JavaScript moderna para requisições de rede, popular pela sua simplicidade, flexibilidade e recursos avançados em relação ao XMLHttpRequest.
A Fetch API é um recurso fundamental do JavaScript que permite fazer requisições de rede (baixar dados, enviar formulários, comunicar-se com APIs) e retorna uma Promise. É a substituição moderna do antigo XMLHttpRequest e funciona naturalmente com async/await. Este guia abrange os padrões mais comuns: requisições GET e POST, inspeção da resposta, leitura de JSON e texto, envio de cabeçalhos e tratamento de erros — usando a API gratuita JSONPlaceholder para exemplos executáveis.
Entendendo a Fetch API
A Fetch API foi criada para comunicação em rede e utiliza um sistema baseado em promises para recuperar recursos. É flexível o suficiente para gerenciar diferentes formatos de dados e requisições complexas, tornando-a uma excelente escolha para o desenvolvimento de aplicações web.
A assinatura básica é fetch(url, options). Ela retorna uma promise que é resolvida com um objeto Response assim que o servidor responde com os cabeçalhos — antes que o corpo tenha terminado de ser transferido. Em seguida, você lê o corpo separadamente com um método como .json() ou .text(), cada um retornando sua própria promise.
Um ponto importante: fetch() só rejeita em caso de falha de rede (sem conexão, erro de DNS, bloqueio de CORS). Ela não rejeita em erros HTTP como 404 ou 500 — esses ainda são resolvidos com sucesso. Você deve verificar response.ok (ou response.status) por conta própria.
Uso Básico do Fetch
Vamos explorar um exemplo básico de busca de dados de um post no JSONPlaceholder:
Este trecho busca dados de um post específico, demonstrando como o Fetch retorna uma promise que é resolvida com a resposta da requisição. A resposta é então analisada como JSON e exibida no console.
Inspecionando a Resposta
O objeto Response carrega metadados úteis antes mesmo de você ler o corpo. As propriedades mais importantes são:
response.ok— um boolean que étruepara códigos de status no intervalo de 200 a 299.response.status— o código de status HTTP numérico (ex.:200,404,500).response.statusText— a mensagem de texto que acompanha o status (ex.:"OK").response.headers— um objetoHeadersque você pode consultar com.get().
Lendo o Corpo: .json() vs .text()
O corpo de uma resposta pode ser lido em vários formatos. Cada método retorna uma promise e só pode ser chamado uma vez por resposta — o corpo é um stream que é consumido:
response.json()— analisa o corpo como JSON e resolve para um object ou array JavaScript.response.text()— resolve para o corpo bruto como uma string. Útil para texto simples, HTML, ou quando você quer tratar o parsing de JSON por conta própria.response.blob()— resolve para umBlob, para dados binários como imagens ou arquivos.
Tratamento de Erros no Fetch
O tratamento de erros é fundamental ao trabalhar com requisições de rede. Como fetch() não lança exceções em erros de status HTTP, o padrão usual é verificar response.ok e lançar seu próprio erro quando ele for false. Veja um exemplo com tratamento de erros:
Neste exemplo, verificamos se a resposta é bem-sucedida; caso contrário, um erro é lançado. O método .catch() captura quaisquer erros, preservando a integridade da aplicação.
Implementando uma Requisição POST
A Fetch API não se limita a requisições GET; ela também é capaz de lidar com requisições POST para enviar dados a um servidor. Passe um segundo argumento com method, um body e headers. Ao enviar JSON, você deve tanto serializar o corpo com JSON.stringify() quanto definir o cabeçalho Content-Type para que o servidor saiba como analisá-lo. Veja como criar um novo post no JSONPlaceholder:
Este trecho de código demonstra o envio de uma requisição POST com dados JSON, especificando o método, o corpo e os cabeçalhos. Ele ilustra a versatilidade da Fetch API no tratamento de diferentes tipos de requisição.
Enviando Cabeçalhos de Requisição Personalizados
Os cabeçalhos são a forma de informar ao servidor sobre a requisição — o tipo de conteúdo, o formato de resposta esperado ou credenciais de autenticação como um token bearer. Você pode passar cabeçalhos como um object simples, ou construí-los com a classe Headers para maior controle:
Nota: uma requisição para outra origem só será bem-sucedida se o servidor de destino permitir isso via CORS. Veja Fetch: Requisições Cross-Origin para entender como as regras de cross-origin afetam cabeçalhos e credenciais.
Usando Async/Await com Fetch
Para uma abordagem mais elegante ao código assíncrono, a Fetch API pode ser combinada com async e await. Este método oferece uma sintaxe mais legível, semelhante ao código síncrono:
Usando async e await, este exemplo busca um post, aguarda a resposta e a processa dentro de um bloco try/catch para tratamento de erros. Ele demonstra como os recursos modernos do JavaScript podem simplificar o uso da Fetch API.
Tratando Erros com Async/Await
Quando se trata de tratamento de erros com async/await, isso é normalmente feito usando blocos try-catch.
Para tratar erros que possam ocorrer durante operações assíncronas, você pode envolver suas chamadas await dentro de um bloco try e capturar qualquer erro com um bloco catch. Veja como adicionar tratamento de erros à função fetchData:
Propagação de Erros
A propagação de erros é a forma como um erro "se move" ou é transmitido de uma parte do seu programa para outra. Pense nisso como o caminho que um erro percorre após ocorrer. Quando um erro acontece, é como soltar uma bola. A propagação de erros trata de para onde a bola vai depois de ser solta: alguém a pega, ou ela cai no chão?
Em JavaScript, isso geralmente ocorre por meio do encadeamento de rejeições de promises, onde uma rejeição não tratada percorre a pilha de chamadas até que um bloco catch ou um handler global a intercepte.
No exemplo abaixo, se você quiser que os erros sejam tratados pela função chamadora (como viewData), você deve evitar capturá-los em fetchData ou relançá-los após capturá-los:
Como você pode ver, o mesmo objeto de erro é capturado em ambas as funções porque o relançamos de fetchData para viewData.
Tópicos Relacionados
Para se aprofundar na Fetch API, explore estes capítulos relacionados:
- JavaScript Promise — a base sobre a qual o Fetch é construído.
- Async/Await — a forma mais limpa de escrever chamadas com Fetch.
- Fetch: Abort — cancele uma requisição com
AbortController(útil para timeouts e busca enquanto digita). - Fetch: Requisições Cross-Origin — como o CORS controla requisições para outros domínios.
Conclusão
A Fetch API é uma ferramenta indispensável para desenvolvedores JavaScript, aprimorando aplicações web com sua abordagem baseada em promises para requisições de rede. Por meio de exemplos práticos, este guia demonstra como a Fetch API pode ser utilizada efetivamente para buscar dados, tratar erros e fazer requisições POST, aproveitando a API JSONPlaceholder para aplicações do mundo real. Dominar a Fetch API capacita os desenvolvedores a criar aplicações web mais responsivas, dinâmicas e robustas.