<h2>Introdução à Fetch API</h2>
<p>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.</p>
<p>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.</p>
<h2>Fundamentos e Sintaxe Básica</h2>
<h3>GET: Recuperando Dados</h3>
<p>A forma mais simples de usar Fetch é fazer uma requisição GET para obter dados. A função <code>fetch()</code> retorna uma Promise que resolve para um objeto <code>Response</code>. Você deve chamar <code>.json()</code> para parsear o corpo da resposta como JSON.</p>
<pre><code class="language-javascript">// 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));</code></pre>
<p>A versão com async/await é mais legível e se tornou o padrão na indústria:</p>
<pre><code class="language-javascript">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();</code></pre>
<h3>POST: Enviando Dados</h3>
<p>Para criar novos recursos, use POST com um objeto de configuração contendo o método HTTP e os headers necessários:</p>
<pre><code class="language-javascript">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);
}
}</code></pre>
<h2>Tratamento de Erros e Status HTTP</h2>
<h3>Verificando o Status da Resposta</h3>
<p>Um erro crítico que iniciantes cometem é acreditar que <code>fetch()</code> rejeita a Promise em caso de erro HTTP. Na verdade, <code>fetch()</code> só rejeita em casos de falha de rede. Você deve verificar manualmente <code>response.ok</code> ou <code>response.status</code>:</p>
<pre><code class="language-javascript">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);
}
}</code></pre>
<h3>AbortController: Cancelando Requisições</h3>
<p>Em aplicações reais, você frequentemente precisa cancelar requisições (quando um usuário navega para outra página, por exemplo). Use <code>AbortController</code>:</p>
<pre><code class="language-javascript">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));</code></pre>
<h2>Padrões Avançados e Boas Práticas</h2>
<h3>Função Helper Reutilizável</h3>
<p>Crie uma função wrapper que centraliza configurações comuns, como headers de autenticação:</p>
<pre><code class="language-javascript">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));</code></pre>
<h3>Tratando Diferentes Tipos de Resposta</h3>
<p>Nem sempre a resposta é JSON. Use <code>response.headers.get('content-type')</code> para validar:</p>
<pre><code class="language-javascript">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;
}</code></pre>
<h3>Upload de Arquivos com FormData</h3>
<p>Para enviar arquivos, use <code>FormData</code> em vez de JSON:</p>
<pre><code class="language-javascript">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();
}</code></pre>
<h2>Conclusão</h2>
<p>Você aprendeu que <strong>Fetch API é a forma moderna e nativa de consumir APIs REST</strong>, eliminando a necessidade de bibliotecas externas para operações básicas. Dominar async/await e a importância de validar <code>response.ok</code> 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.</p>
<h2>Referências</h2>
<ul>
<li><a href="https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API" target="_blank" rel="noopener noreferrer">MDN Web Docs - Fetch API</a></li>
<li><a href="https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch" target="_blank" rel="noopener noreferrer">MDN - Using Fetch</a></li>
<li><a href="https://eloquentjavascript.net/18_http.html" target="_blank" rel="noopener noreferrer">Eloquent JavaScript - HTTP and Forms</a></li>
<li><a href="https://web.dev/introduction-to-fetch/" target="_blank" rel="noopener noreferrer">Web.dev - Introduction to fetch()</a></li>
<li><a href="https://javascript.info/fetch" target="_blank" rel="noopener noreferrer">JavaScript.info - Fetch API</a></li>
</ul>