O que Todo Dev Deve Saber sobre Fetch API em JavaScript: Consumindo APIs REST no Navegador Já leu

Introdução à Fetch API A Fetch API é a forma moderna e padronizada de fazer requisições HTTP no navegador, substituindo completamente o XMLHttpRequest. Ela oferece uma interface limpa baseada em Promises, tornando o consumo de APIs REST intuitivo e elegante. Quando você precisa buscar dados de um servidor, autenticar usuários ou enviar formulários sem recarregar a página, a Fetch API é sua ferramenta ideal. Diferentemente de bibliotecas externas como Axios, a Fetch API é nativa do JavaScript moderno (disponível em todos os navegadores atuais). Isso significa zero dependências e melhor performance. Você escreve menos código, trata erros de forma consistente e integra-se perfeitamente com async/await. Fundamentos e Sintaxe Básica GET: Recuperando Dados A forma mais simples de usar Fetch é fazer uma requisição GET para obter dados. A função retorna uma Promise que resolve para um objeto . Você deve chamar para parsear o corpo da resposta como JSON. A versão com async/await é mais legível e se tornou o

Introdução à Fetch API

A Fetch API é a forma moderna e padronizada de fazer requisições HTTP no navegador, substituindo completamente o XMLHttpRequest. Ela oferece uma interface limpa baseada em Promises, tornando o consumo de APIs REST intuitivo e elegante. Quando você precisa buscar dados de um servidor, autenticar usuários ou enviar formulários sem recarregar a página, a Fetch API é sua ferramenta ideal.

Diferentemente de bibliotecas externas como Axios, a Fetch API é nativa do JavaScript moderno (disponível em todos os navegadores atuais). Isso significa zero dependências e melhor performance. Você escreve menos código, trata erros de forma consistente e integra-se perfeitamente com async/await.

Fundamentos e Sintaxe Básica

GET: Recuperando Dados

A forma mais simples de usar Fetch é fazer uma requisição GET para obter dados. A função fetch() retorna uma Promise que resolve para um objeto Response. Você deve chamar .json() para parsear o corpo da resposta como JSON.

// Requisição GET básica
fetch('https://jsonplaceholder.typicode.com/posts/1')
  .then(response => response.json())
  .then(data => console.log(data))
  .catch(error => console.error('Erro:', error));

A versão com async/await é mais legível e se tornou o padrão na indústria:

async function obterPost() {
  try {
    const response = await fetch('https://jsonplaceholder.typicode.com/posts/1');
    const data = await response.json();
    console.log(data);
  } catch (error) {
    console.error('Erro na requisição:', error);
  }
}

obterPost();

POST: Enviando Dados

Para criar novos recursos, use POST com um objeto de configuração contendo o método HTTP e os headers necessários:

async function criarPost() {
  try {
    const response = await fetch('https://jsonplaceholder.typicode.com/posts', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({
        title: 'Novo Post',
        body: 'Conteúdo do post',
        userId: 1
      })
    });

    const data = await response.json();
    console.log('Post criado:', data);
  } catch (error) {
    console.error('Erro ao criar post:', error);
  }
}

Tratamento de Erros e Status HTTP

Verificando o Status da Resposta

Um erro crítico que iniciantes cometem é acreditar que fetch() rejeita a Promise em caso de erro HTTP. Na verdade, fetch() só rejeita em casos de falha de rede. Você deve verificar manualmente response.ok ou response.status:

async function buscarComValidacao() {
  try {
    const response = await fetch('https://jsonplaceholder.typicode.com/posts/999');

    if (!response.ok) {
      throw new Error(`Erro HTTP: ${response.status}`);
    }

    const data = await response.json();
    console.log(data);
  } catch (error) {
    console.error('Erro capturado:', error.message);
  }
}

AbortController: Cancelando Requisições

Em aplicações reais, você frequentemente precisa cancelar requisições (quando um usuário navega para outra página, por exemplo). Use AbortController:

const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), 5000);

fetch('https://jsonplaceholder.typicode.com/posts', {
  signal: controller.signal
})
  .then(response => response.json())
  .then(data => console.log(data))
  .catch(error => {
    if (error.name === 'AbortError') {
      console.log('Requisição cancelada');
    }
  })
  .finally(() => clearTimeout(timeoutId));

Padrões Avançados e Boas Práticas

Função Helper Reutilizável

Crie uma função wrapper que centraliza configurações comuns, como headers de autenticação:

async function apiRequest(endpoint, options = {}) {
  const defaultOptions = {
    headers: {
      'Content-Type': 'application/json',
      'Authorization': `Bearer ${localStorage.getItem('token')}`
    }
  };

  const config = { ...defaultOptions, ...options };
  const response = await fetch(`https://api.exemplo.com${endpoint}`, config);

  if (!response.ok) {
    throw new Error(`API Error: ${response.status}`);
  }

  return response.json();
}

// Uso
apiRequest('/usuarios', { method: 'GET' })
  .then(usuarios => console.log(usuarios))
  .catch(error => console.error(error));

Tratando Diferentes Tipos de Resposta

Nem sempre a resposta é JSON. Use response.headers.get('content-type') para validar:

async function processarResposta() {
  const response = await fetch('https://jsonplaceholder.typicode.com/posts/1');
  const contentType = response.headers.get('content-type');

  let data;
  if (contentType.includes('application/json')) {
    data = await response.json();
  } else if (contentType.includes('text/plain')) {
    data = await response.text();
  } else {
    data = await response.blob();
  }

  return data;
}

Upload de Arquivos com FormData

Para enviar arquivos, use FormData em vez de JSON:

async function enviarArquivo(arquivo) {
  const formData = new FormData();
  formData.append('arquivo', arquivo);
  formData.append('descricao', 'Meu arquivo');

  const response = await fetch('https://api.exemplo.com/upload', {
    method: 'POST',
    body: formData
    // Note: não defina 'Content-Type', o navegador faz isso automaticamente
  });

  return response.json();
}

Conclusão

Você aprendeu que Fetch API é a forma moderna e nativa de consumir APIs REST, eliminando a necessidade de bibliotecas externas para operações básicas. Dominar async/await e a importância de validar response.ok são fundamentos críticos que diferenciam código profissional de código frágil. Por fim, padrões como funções helpers e AbortController transformam requisições simples em sistemas robusto, prontos para produção.

Referências


Artigos relacionados