#JavaScript #Webdesign

Fetch API

Introdução a Fetch API

A Fetch API é uma interface moderna do JavaScript projetada para realizar requisições de rede assíncronas (comumente chamadas de AJAX), permitindo que uma página web se comunique com servidores para buscar ou enviar dados sem a necessidade de recarregar o documento inteiro.

Abaixo estão os pontos principais sobre o funcionamento e a utilização desta API, conforme as fontes:

1. Propósito e Evolução

2. Sintaxe e Funcionamento

3. Configurações Avançadas (POST e Outros Métodos)

4. Vantagens Práticas

Diferença entre o Ajax e Fetch

A principal diferença entre os dois reside na sua natureza: o fetch é uma interface moderna e nativa do JavaScript para realizar requisições de rede assíncronas, enquanto o $.ajax é um método pertencente à biblioteca de terceiros jQuery.

Abaixo estão detalhadas as principais distinções técnicas e contextuais:

1. Origem e Propósito

2. Estrutura Lógica e Gerenciamento

3. Performance e Peso

4. Compatibilidade

Exemplo Prático: Busca de Cidades por Estado

Neste cenário, quando um usuário escolhe um estado em um formulário (evento onchange), a Fetch API é disparada para buscar a lista de municípios correspondentes.

1. A Estrutura da Requisição (GET): A função fetch() inicia a conexão com a URL do serviço. Como o processo é assíncrono e pode demorar, utiliza-se a estrutura de promessas com o método .then() para definir o que será feito quando o resultado chegar.

2. Manipulação do DOM com os Dados: Após receber o JSON, o código percorre a lista de cidades usando um laço for. Para cada item, o JavaScript cria dinamicamente um novo elemento HTML do tipo <option>, preenche seu valor com o ID da cidade e seu texto visível com o nome, adicionando-o em seguida a um campo de seleção (<select>) na página,.

A Estrutura da Requisição (GET) utilizando a Fetch API é o método moderno e padronizado para solicitar informações de um servidor de forma assíncrona, garantindo que o site continue funcional enquanto os dados are carregados.

Diferente de métodos antigos ou bibliotecas como jQuery, a Fetch API utiliza uma estrutura baseada em Promessas (Promises) para gerenciar o tempo de espera da resposta do servidor. Abaixo, detalhamos os componentes dessa estrutura:

1. A Chamada Inicial: fetch(url)

A requisição começa com a função fetch(), que recebe como parâmetro obrigatório a URL do serviço (API) que se deseja acessar.

Exemplo JavaScript:

// 1. URL para obter os estados ordenados por nome
const urlEstados = 'https://servicodados.ibge.gov.br/api/v1/localidades/estados?orderBy=nome';

const ufSelect = document.getElementById('uf');
const municipioSelect = document.getElementById('municipios');

// 2. Preencher o select de estados assim que a página carregar
fetch(urlEstados)
  .then(response => response.json())
  .then(data => {
    let itens = '<option value="">Selecione o Estado</option>';
    data.forEach(val => {
      itens += `<option value="${val.sigla}">${val.sigla} - ${val.nome}</option>`;
    });
    ufSelect.innerHTML = itens;
  })
  .catch(error => {
    console.error("Erro ao carregar estados:", error);
    ufSelect.innerHTML = '<option>Erro ao carregar</option>';
  });

// 3. Carregar os municípios quando um estado for selecionado
ufSelect.addEventListener('change', function () {
  let uf = this.value;
  if (!uf) return;
  let url = `https://servicodados.ibge.gov.br/api/v1/localidades/estados/${uf}/municipios`;

  fetch(url)
    .then(response => response.json())
    .then(data => {
      let conteudo = '<option value="">Selecione o Município</option>';
      data.forEach(val => {
        conteudo += `<option value="${val.id}">${val.nome}</option>`;
      });
      municipioSelect.innerHTML = conteudo;
    })
    .catch(error => {
      console.error("Erro ao carregar municípios:", error);
      municipioSelect.innerHTML = '<option>Erro ao carregar</option>';
    });
});

2. O Primeiro Contato: O Objeto response

Como a rede pode demorar, o fetch() retorna uma "promessa" de resposta. Quando o servidor finalmente responde, o primeiro método .then() é acionado.

Exemplo:

fetch('https://servicodados.ibge.gov.br/api/v1/localidades/estados')
  .then(response => {
    // O objeto 'response' contém detalhes da resposta do servidor
    console.log('Status HTTP:', response.status); // Ex: 200
    console.log('Sucesso (ok):', response.ok);   // true se status entre 200-299
    
    // Verificando um cabeçalho específico
    console.log('Tipo do conteúdo:', response.headers.get('Content-Type'));

    // Extraindo o corpo da resposta como JSON para o próximo .then()
    return response.json();
  });

3. O Recebimento dos Dados: O Segundo .then()

Uma vez que o processamento do JSON é concluído (o que também leva um tempo mínimo), um segundo .then() é executado.

Exemplo:

fetch('https://servicodados.ibge.gov.br/api/v1/localidades/estados')
  .then(response => response.json()) // Primeiro .then(): extrai o JSON
  .then(data => {
    // Segundo .then(): os dados estão prontos!
    // 'data' é o array de objetos que o servidor enviou
    console.log('Dados recebidos:', data);

    // Exemplo de uso: listando os nomes dos estados no console
    data.forEach(estado => {
      console.log(`Estado: ${estado.nome} - Sigla: ${estado.sigla}`);
    });

    // Aqui você poderia atualizar elementos HTML com os dados
  });

O exemplo demonstra como os dados (já convertidos para objeto JavaScript no primeiro .then()) são manipulados no segundo bloco, utilizando um forEach para listar estados no console.

4. Tratamento de Falhas: O Método .catch()

Embora a estrutura básica foque no sucesso, uma requisição profissional deve prever falhas (como queda de internet ou servidor fora do ar). Para isso, utiliza-se o método .catch() ao final da corrente, que captura qualquer erro ocorrido em qualquer uma das etapas anteriores.

Essa estrutura em "cascata" (encadeamento) torna o código mais limpo e fácil de ler do que as abordagens antigas baseadas em múltiplos callbacks aninhados.

Exemplo:

fetch('https://api.exemplo.com/dados')
  .then(response => {
    // Importante: o fetch não rejeita automaticamente erros HTTP (como 404 ou 500)
    // O .catch só é disparado sozinho em falhas de rede (ex: sem internet).
    // Por isso, verificamos a propriedade .ok e lançamos um erro manualmente se necessário.
    if (!response.ok) {
      throw new Error(`Erro HTTP! Status: ${response.status}`);
    }
    return response.json();
  })
  .then(data => {
    console.log('Dados recebidos:', data);
  })
  .catch(error => {
    // Este bloco captura:
    // 1. Falhas de conexão/rede
    // 2. Erros lançados manualmente com 'throw new Error' no .then anterior
    // 3. Erros de sintaxe ou processamento dentro dos .then()
    console.error('Ocorreu um erro na requisição:', error.message);
  });

Envio de Dados (POST)

Além de buscar informações, a Fetch API também pode ser configurada para enviar dados a um banco de dados.

Essa abordagem garante uma experiênciade usuário fluida, pois o navegador continua operacional enquanto o JavaScript realiza o intercâmbio de dados em "segundo plano".

Exemplo:

const url = 'https://jsonplaceholder.typicode.com/posts'; // Exemplo de API pública para testes

// Dados que serão enviados
const novoPost = {
  title: 'Aprendendo Fetch API',
  body: 'Este é um exemplo de envio de dados usando o método POST.',
  userId: 1
};

fetch(url, {
  method: 'POST', // Define o método como POST
  headers: {
    'Content-Type': 'application/json' // Indica que o conteúdo é um JSON
  },
  body: JSON.stringify(novoPost) // Converte o objeto JS em string JSON
})
  .then(response => {
    if (!response.ok) {
      throw new Error('Erro na rede ou no servidor');
    }
    return response.json();
  })
  .then(data => {
    console.log('Sucesso! Resposta do servidor:', data);
    // Aqui você pode atualizar a interface para confirmar o envio
  })
  .catch(error => {
    console.error('Houve um problema com a requisição:', error);
  });

Principais detalhes do exemplo:

  1. method: Define que a operação é de criação/envio de dados.
  2. headers: O cabeçalho Content-Type: application/json é essencial para que o servidor saiba como interpretar os dados recebidos.
  3. body: Os dados devem ser enviados como uma string. O método JSON.stringify() faz essa conversão automaticamente para nós.

Referências