O Axios é um cliente HTTP baseado em Promises, popular para fazer requisições assíncronas no navegador e em ambientes Node.js. Ele simplifica a interação com APIs RESTful, oferecendo uma API intuitiva e recursos robustos.
Principais Métodos HTTP para Interação com APIs
Para interagir com recursos em um servidor, o Axios oferece métodos convenientes que correspondem aos verbos HTTP padrão:
GET: Utilizado para recuperar dados de um servidor, geralmente para operações de leitura.POST: Empregado para enviar novos dados ao servidor, como o envio de um formulário ou o upload de um arquivo.PUT: Usado para atualizar completamente um recurso existente no servidor.PATCH: Destinado à atualização parcial de um recurso existente.DELETE: Utilizado para remover um recurso específico do servidor.
Visão Geral dos Métodos da API Axios
O Axios fornece uma variedade de métodos para diferentes tipos de requisições:
axios.request(config): Método genérico para executar qualquer tipo de requisição com uma configuração abrangente.axios.get(url[, config]): Envia uma requisição GET.axios.delete(url[, config]): Envia uma requisição DELETE.axios.head(url[, config]): Envia uma requisição HEAD.axios.options(url[, config]): Envia uma requisição OPTIONS.axios.post(url[, data[, config]]): Envia uma requisição POST com dados no corpo.axios.put(url[, data[, config]]): Envia uma requisição PUT com dados no corpo.axios.patch(url[, data[, config]]): Envia uma requisição PATCH com dados no corpo.
Opções de Configuração para Requisições Axios
Ao realizar requisições, você pode personalizar o comportamento do Axios por meio de um objeto de configuração detalhado:
{
// `url` é o endpoint do recurso no servidor
url: '/recurso',
// `method` define o método HTTP a ser usado na requisição (padrão: 'get')
method: 'get',
// `baseURL` será prefixado à `url` a menos que a `url` seja absoluta.
// Útil para definir um domínio base para todas as requisições de uma instância.
baseURL: 'https://minhaapi.com/v1/',
// `transformRequest` permite modificar os dados da requisição antes de serem enviados ao servidor.
// Aplicável apenas para métodos 'PUT', 'POST', 'PATCH'.
transformRequest: [function (dados, cabecalhos) {
// Exemplo: converter objeto para FormData
return dados;
}],
// `transformResponse` permite modificar os dados da resposta antes de serem passados para then/catch.
transformResponse: [function (dados) {
// Exemplo: parsear dados JSON brutos
return dados;
}],
// `headers` são cabeçalhos HTTP personalizados a serem enviados com a requisição.
headers: {'Content-Type': 'application/json'},
// `params` são parâmetros de URL que serão anexados à URL da requisição.
// Deve ser um objeto simples ou uma instância de URLSearchParams.
params: {
idUsuario: 123
},
// `paramsSerializer` é uma função para serializar o objeto `params`.
// Por exemplo, para lidar com arrays em parâmetros de URL (e.g., usando 'qs').
paramsSerializer: function(parametros) {
// return Qs.stringify(parametros, {arrayFormat: 'brackets'})
return new URLSearchParams(parametros).toString();
},
// `data` são os dados a serem enviados como corpo da requisição.
// Aplicável apenas para métodos 'PUT', 'POST', 'PATCH'.
// Pode ser string, objeto simples, ArrayBuffer, FormData, etc.
data: {
primeiroNome: 'João',
ultimoNome: 'Silva'
},
// `timeout` especifica o tempo limite da requisição em milissegundos (0 = sem tempo limite).
// Se a requisição exceder este tempo, ela será abortada.
timeout: 5000,
// `withCredentials` indica se cookies de credenciais devem ser enviados em requisições cross-domain.
withCredentials: false,
// `adapter` permite personalizar como a requisição é tratada, útil para testes.
adapter: function (configuracao) {
/* ... Implementação personalizada ... */
},
// `auth` define credenciais para autenticação HTTP básica.
auth: {
usuario: 'admin',
senha: 'senhaSecreta'
},
// `responseType` indica o tipo de dado esperado na resposta do servidor.
// Opções: 'arraybuffer', 'blob', 'document', 'json', 'text', 'stream'.
responseType: 'json',
// `responseEncoding` indica a codificação a ser usada para decodificar respostas.
// Ignorado para 'stream' ou requisições no lado do cliente.
responseEncoding: 'utf8',
// `xsrfCookieName` é o nome do cookie a ser usado como token XSRF.
xsrfCookieName: 'XSRF-TOKEN',
// `xsrfHeaderName` é o nome do cabeçalho HTTP que contém o token XSRF.
xsrfHeaderName: 'X-XSRF-TOKEN',
// `onUploadProgress` permite lidar com eventos de progresso de upload.
onUploadProgress: function (eventoProgresso) {
// Lógica para atualizar a barra de progresso
},
// `onDownloadProgress` permite lidar com eventos de progresso de download.
onDownloadProgress: function (eventoProgresso) {
// Lógica para atualizar a barra de progresso
},
// `maxContentLength` define o tamanho máximo permitido para o conteúdo da resposta.
maxContentLength: 2000,
// `validateStatus` define quais códigos de status HTTP devem resolver (sucesso) ou rejeitar (erro) a Promise.
// Se retornar `true`, a Promise é resolvida; caso contrário, é rejeitada.
validateStatus: function (status) {
return status >= 200 && status < 300; // Padrão: aceita status 2xx
},
// `maxRedirects` define o número máximo de redirecionamentos a seguir em Node.js.
maxRedirects: 5,
// `socketPath` define um Socket UNIX a ser usado em Node.js.
socketPath: null,
// `httpAgent` e `httpsAgent` definem agentes personalizados para requisições HTTP e HTTPS em Node.js.
// Exemplo: new http.Agent({ keepAlive: true }) para manter conexões.
httpAgent: null,
httpsAgent: null,
// `proxy` configura um servidor proxy para a requisição.
proxy: {
host: '127.0.0.1',
port: 9000,
auth: {
usuario: 'proxyUser',
senha: 'proxyPassword'
}
},
// `cancelToken` especifica um token para cancelar a requisição.
cancelToken: new axios.CancelToken(function (cancelar) { })
}
Estrutura do Objeto de Resposta
Quando uma requisição é bem-sucedida, o Axios retorna um objeto Promise que, ao ser resolvido, oferece acesso a um objeto de resposta com as seguintes propriedades:
{
// `data` são os dados fornecidos pelo servidor
dados: {},
// `status` é o código de status HTTP da resposta do servidor
status: 200,
// `statusText` é a mensagem de status HTTP da resposta do servidor
statusTexto: 'OK',
// `headers` são os cabeçalhos da resposta do servidor
cabecalhos: {},
// `config` é o objeto de configuração utilizado para a requisição
config: {},
// `request` é a instância da requisição que gerou esta resposta
// (XMLHttpRequest no navegador, ClientRequest no Node.js)
requisicao: {}
}
Você pode acessar essas propriedades no callback .then():
axios.get('/api/usuarios/101')
.then(function(resposta) {
console.log('Dados recebidos:', resposta.dados);
console.log('Status HTTP:', resposta.status);
console.log('Mensagem de Status:', resposta.statusTexto);
console.log('Cabeçalhos da Resposta:', resposta.cabecalhos);
console.log('Configuração da Requisição:', resposta.config);
})
.catch(function(erro) {
console.error('Ocorreu um erro na requisição:', erro);
});
Exemplos Práticos: Requisições GET
Exemplo 1: Obtendo e Renderizando Dados em uma Lista
Este exemplo demonstra como buscar dados e exibi-los em uma lista HTML. Assumimos um framework reativo como Vue.js ou React, mas a lógica do Axios é agnóstica.
<template>
<div>
<button @click="carregarProdutos">Buscar Produtos</button>
<ul v-if="listaProdutos.length">
<li v-for="produto in listaProdutos" :key="produto.id">
{{ produto.id }} - {{ produto.nome }} (Fabricante: {{ produto.fabricante }})
</li>
</ul>
<p v-else>Nenhum produto encontrado.</p>
</div>
</template>
<script>
import axios from 'axios';
export default {
data() {
return {
listaProdutos: []
};
},
methods: {
carregarProdutos() {
axios.get('/api/produtos')
.then(response => {
console.log('Resposta completa:', response);
this.listaProdutos = response.data; // 'data' contém os dados reais da resposta
})
.catch(error => {
console.error('Falha ao carregar produtos:', error);
});
}
}
};
</script>
Exemplo 2: Requisições GET com Parâmetros de Query
Para enviar parâmetros na URL (http://localhost:8080/api/itens?id=1), você pode usar o objeto params ou construir a URL diretamente:
// Usando o objeto 'params' na configuração
this.$axios.get('/api/itens', {
params: {
itemId: 1
}
})
.then(resposta => {
console.log(resposta.data);
})
.catch(erro => {
console.error('Erro na requisição:', erro);
});
// Ou construindo a URL com parâmetros manualmente (menos recomendado para múltiplos parâmetros)
this.$axios.get('/api/itens?itemId=1')
.then(resposta => {
console.log(resposta.data);
})
.catch(erro => {
console.error('Erro na requisição:', erro);
});
// Utilizando a sintaxe completa com o método 'request'
this.$axios({
method: 'get',
url: '/api/itens',
params: {
itemId: 1
}
})
.then(resposta => {
console.log(resposta.data);
})
.catch(erro => {
console.error('Erro na requisição:', erro);
});
Exemplos Práticos: Requisições POST
Exemplo 1: Adicionando um Novo Recurso
Para enviar dados no corpo da requisição POST:
data() {
return {
novoItem: {
titulo: '',
descricao: ''
}
};
},
methods: {
adicionarNovoItem() {
axios.post("/api/posts", this.novoItem)
.then(response => {
console.log("Item criado com sucesso:", response.data);
this.carregarItens(); // Atualiza a lista após a criação
})
.catch(error => {
console.error("Erro ao criar item:", error);
});
}
}
Exemplo 2: Requisição POST Direta
// Envio de dados diretamente como objeto no corpo da requisição
axios.post('/api/usuarios', {
nome: 'Alice',
idade: 30
})
.then(resposta => {
console.log('Usuário registrado:', resposta.data);
})
.catch(erro => {
console.error('Erro no registro:', erro);
});
// Usando a sintaxe completa com o método 'request'
this.$axios({
method: 'post',
url: '/api/usuarios',
data: {
nome: 'Bob',
idade: 25
}
})
.then(resposta => {
console.log('Usuário registrado:', resposta.data);
})
.catch(erro => {
console.error('Erro no registro:', erro);
});
Requisições Concorrentes
O Axios permite executar múltiplas requisições em paralelo e esperar por todas elas usando axios.all() e axios.spread():
function obterInformacoesCliente() {
return axios.get('/api/clientes/123');
}
function obterHistoricoCompras() {
return axios.get('/api/clientes/123/compras');
}
axios.all([obterInformacoesCliente(), obterHistoricoCompras()])
.then(axios.spread(function (infoCliente, historico) {
// Ambos os dados (infoCliente e historico) estão agora disponíveis
console.log('Detalhes do Cliente:', infoCliente.data);
console.log('Histórico de Compras:', historico.data);
}))
.catch(erro => {
console.error('Erro em uma das requisições concorrentes:', erro);
});
Modernizando com Async/Await
async e await oferecem uma maneira mais síncrona e legível de escrever código assíncrono. Uma função marcada como async sempre retorna uma Promise. O operador await pode ser usado dentro de funções async para pausar a execução até que uma Promise seja resolvida ou rejeitada, tornando o fluxo de controle mais linear.
async function adicionarNovoProdutoAsync() {
try {
const resposta = await axios.post("/api/produtos", this.dadosProduto);
console.log("Produto adicionado:", resposta.data);
await this.atualizarListaProdutos(); // Chama outra função assíncrona
console.log("Lista de produtos atualizada.");
} catch (erro) {
console.error("Erro ao adicionar produto:", erro);
}
}
Exemplos Práticos: PUT, PATCH e DELETE
Requisições PUT (Atualização Completa)
this.$axios.put('/api/recursos/5', {
novoCampo: 'valorAtualizado',
outroCampo: 'novoValor'
})
.then(resposta => {
console.log('Recurso atualizado completamente:', resposta.data);
})
.catch(erro => {
console.error('Erro ao atualizar recurso (PUT):', erro);
});
Requisições PATCH (Atualização Parcial)
this.$axios.patch('/api/recursos/5', {
apenasEsteCampo: 'valorAlterado'
})
.then(resposta => {
console.log('Recurso atualizado parcialmente:', resposta.data);
})
.catch(erro => {
console.error('Erro ao atualizar recurso (PATCH):', erro);
});
Requisições DELETE (Remoção de Dados)
Para requisições DELETE, você pode enviar parâmetros na URL (via params) ou no corpo da requisição (via data).
Deletar com Parâmetros na URL (Query String)
// Usando o objeto 'params' para anexar à URL
axios.delete("/api/registros", {
params: {
registroId: 15
}
})
.then(response => {
console.log('Registro deletado via URL params:', response);
})
.catch(error => {
console.error('Erro ao deletar registro (URL params):', error);
});
// Ou diretamente na URL (string de query)
axios.delete("/api/registros?registroId=16")
.then(response => {
console.log('Registro deletado via URL direta:', response);
})
.catch(error => {
console.error('Erro ao deletar registro (URL direta):', error);
});
// Sintaxe completa com método 'request'
let paramsParaDeletar = { idParaRemover: 17 };
axios({
method: 'delete',
url: '/api/registros',
params: paramsParaDeletar
})
.then(response => {
console.log('Registro deletado via config params:', response);
})
.catch(error => {
console.error('Erro ao deletar registro (config params):', error);
});
Deletar com Dados no Corpo da Requisição (Body)
// Usando o objeto 'data' para enviar no corpo da requisição
axios.delete("/api/registros", {
data: {
identificadorUnico: 20
}
})
.then(response => {
console.log('Registro deletado via corpo da requisição:', response);
})
.catch(error => {
console.error('Erro ao deletar registro (body):', error);
});
// Sintaxe completa com método 'request'
let dadosParaDeletar = { chaveDeleta: 21 };
axios({
method: 'delete',
url: '/api/registros',
data: dadosParaDeletar
})
.then(response => {
console.log('Registro deletado via config data:', response);
})
.catch(error => {
console.error('Erro ao deletar registro (config data):', error);
});
Criação e Configuração de Instâncias Axios
Criar instâncias do Axios permite configurar diferentes comportamentos para diferentes partes da sua aplicação, evitando conflitos e repetindo configurações comuns. Propriedades como baseURL e timeout são ideais para instâncias.
baseURL: O URL base para todas as requisições desta instância (String).timeout: Duração máxima da requisição em ms (padrão: 0, sem limite) (Number).url: Caminho específico da requisição (String).method: Método HTTP (get, post, put, etc.) (String).headers: Objeto com cabeçalhos HTTP personalizados (Object).params: Parâmetros de query para a URL (Object).data: Dados a serem enviados no corpo da requisição (Object).
const apiClientes = axios.create({
baseURL: 'https://api.meusclientes.com/v1/',
timeout: 5000,
headers: {'X-Api-Key': 'abc123def'}
});
// Exemplo de uso
apiClientes.get('/lista-clientes')
.then(response => console.log(response.data))
.catch(error => console.error(error));
Cenários com Múltiplas Instâncias
Se você tem diferentes domínios de API ou requisitos de timeout, pode criar múltiplas instâncias:
<script>
import axios from "axios";
export default {
name: "ComponenteRequisição",
created() {
// Instância para a API de produtos (timeout padrão)
let instanciaProdutos = axios.create({
baseURL: "http://localhost:3000/api",
timeout: 3000,
});
instanciaProdutos.get("/produtos").then((res) => {
console.log("Dados de produtos:", res.data);
});
// Instância para a API de usuários (timeout maior)
let instanciaUsuarios = axios.create({
baseURL: "http://localhost:3001/api",
timeout: 10000,
});
instanciaUsuarios.get("/usuarios").then((res) => {
console.log("Dados de usuários:", res.data);
});
},
};
</script>
Você também pode definir configurações padrão diretamente em uma instância:
let minhaApiConfig = axios.create({
baseURL: "https://minhaempresa.com/api/",
timeout: 7000,
headers: {
'Authorization': 'Bearer meuToken',
'Post-Type': 'application/json;charset=UTF-8'
},
params: { versao: '2.0' }, // Parâmetros de query padrão
data: { origem: 'web' }, // Dados padrão para POST/PUT/PATCH
});
Prioridade das Configurações
As configurações do Axios são mescladas com uma ordem de prioridade específica:
- Configuração de Requisição: Parâmetros passados diretamente na chamada do método (
axios.get('/url', { timeout: 1000 })). - Configuração da Instância: Configurações definidas ao criar uma instância (
axios.create({ timeout: 2500 })). - Configuração Global: Valores padrão do próprio Axios (
axios.defaults.timeout = 0).
// Configuração global padrão (timeout 0)
axios.defaults.timeout = 0; // Desativa timeout global
// Criamos uma instância, sobrescrevendo o timeout global para 2.5 segundos
var apiComTempoLimite = axios.create();
apiComTempoLimite.defaults.timeout = 2500;
// Para uma requisição específica que pode demorar mais, sobrescrevemos o timeout da instância para 5 segundos
apiComTempoLimite.get('/recurso-demorado', {
timeout: 5000
})
.then(response => console.log('Resposta do recurso demorado:', response.data))
.catch(error => console.error('Erro no recurso demorado:', error));
// Para outras requisições da instância, o timeout de 2.5 segundos será aplicado
apiComTempoLimite.get('/recurso-padrao')
.then(response => console.log('Resposta do recurso padrão:', response.data))
.catch(error => console.error('Erro no recurso padrão:', error));
Interceptors (Interceptadores)
Interceptors permitem que você intercepte requisições ou respostas antes que sejam manipuladas por .then() ou .catch(). Isso é útil para adicionar autenticação, logs, manipulação de erros, etc.
Interceptador de Requisição
Executado antes que uma requisição seja enviada:
this.$axios.interceptors.request.use(config => {
// Exemplo: Adicionar um token de autorização a cada requisição
const token = localStorage.getItem('authToken');
if (token) {
config.headers.Authorization = `Bearer ${token}`;
}
console.log('Requisição interceptada:', config.url);
return config; // Sempre retorne a configuração modificada
}, error => {
// Lidar com erros antes que a requisição seja enviada (ex: problemas de configuração)
console.error('Erro no interceptador de requisição:', error);
return Promise.reject(error); // Rejeita a Promise para que o erro seja tratado
});
Interceptador de Resposta
Executado após o recebimento de uma resposta, antes de ser entregue aos callbacks .then() ou .catch():
axios.interceptors.response.use(response => {
// Exemplo: Simplificar a resposta retornando apenas os dados
console.log('Resposta interceptada:', response.config.url);
return response.data; // Retorna apenas os dados, em vez do objeto de resposta completo
}, error => {
// Lidar com erros de resposta (ex: status 401, 500)
console.error('Erro no interceptador de resposta:', error);
if (error.response && error.response.status === 401) {
// Lógica para redirecionar para login, por exemplo
console.log('Sessão expirada. Redirecionando para login...');
}
return Promise.reject(error);
});
Interceptadores para Instâncias Personalizadas
Você pode adicionar interceptadores a instâncias específicas do Axios:
let apiAutenticada = axios.create({
baseURL: 'https://api.segura.com'
});
apiAutenticada.interceptors.request.use(config => {
config.headers.MeuHeader = 'ValorCustomizado';
return config;
});
Reomvendo Interceptadores
Para remover um interceptador, você deve armazenar a referência dele ao criá-lo e depois usar eject:
const idInterceptador = this.$axios.interceptors.request.use(config => {
config.headers.Log = 'Requisição Logada';
return config;
});
// Para remover
this.$axios.interceptors.request.eject(idInterceptador);
console.log('Interceptador de requisição removido.');
Tratamento de Erros
Tanto erros de requisição (antes de serem enviadas) quanto erros de resposta (após o servidor responder) são capturados pelo bloco .catch() da Promise, ou pelos interceptadores de erro.
import axios from "axios";
// Interceptador de Requisição para tratar erros antes do envio
axios.interceptors.request.use(
config => {
console.log('Requisição enviada:', config.url);
return config;
},
error => {
console.error('Erro na configuração da requisição:', error);
// Exibir um toast de erro ou mensagem para o usuário
return Promise.reject(error);
}
);
// Interceptador de Resposta para tratar erros após a resposta do servidor
axios.interceptors.response.use(
response => {
console.log('Resposta recebida:', response.config.url);
return response;
},
error => {
console.error('Erro na resposta da API:', error.response);
// Lógica para exibir mensagens de erro baseadas no status HTTP
if (error.response && error.response.status === 404) {
alert('Recurso não encontrado!');
} else if (error.response && error.response.status === 500) {
alert('Erro interno do servidor!');
}
return Promise.reject(error);
}
);
// Exemplo de requisição com tratamento de erro global e específico
axios.get("/api/recursos-inexistentes")
.then(res => {
console.log('Requisição bem-sucedida:', res.data);
})
.catch(err => {
console.error('Erro tratado no catch da requisição:', err.message);
// Lógica de tratamento de erro específica para esta requisição
});
Configurando Validação de Status HTTP
Você pode personalizar quais códigos de status HTTP são considerados erros. Por padrão, o Axios rejeita Promises para status >= 300.
axios.get('/api/status/exemplo', {
validateStatus: function (status) {
return status >= 200 && status < 400; // Resolve a Promise para status 2xx e 3xx, rejeita para 4xx ou 5xx
}
})
.then(response => console.log('Requisição bem-sucedida (status 2xx ou 3xx):', response.data))
.catch(error => console.error('Requisição com erro (status 4xx ou 5xx):', error));
Cancelamento de Requisições
É possível cancelar requisições em andamento, o que é útil em cenários como buscas com digitação rápida (para evitar resultados obsoletos) ou quando um componente é desmontado antes da conclusão da requisição.
<template>
<div>
<p>Exemplo de Cancelamento de Requisição</p>
<button @click="iniciarBusca">Iniciar Busca Demorada</button>
<button @click="cancelarBusca">Cancelar Busca</button>
<p v-if="resultado">Resultado: {{ resultado }}</p>
<p v-if="erroCancelamento">Erro de Cancelamento: {{ erroCancelamento }}</p>
</div>
</template>
<script>
import axios from "axios";
export default {
name: "CancelamentoRequisição",
data() {
return {
cancelSource: null,
resultado: null,
erroCancelamento: null
};
},
methods: {
iniciarBusca() {
// Cria um novo token de cancelamento
this.cancelSource = axios.CancelToken.source();
this.resultado = null;
this.erroCancelamento = null;
axios.get("/api/recurso-pesado", {
cancelToken: this.cancelSource.token,
})
.then((res) => {
this.resultado = res.data;
console.log("Requisição concluída:", res.data);
})
.catch((err) => {
if (axios.isCancel(err)) {
this.erroCancelamento = err.message;
console.log("Requisição cancelada:", err.message);
} else {
console.error("Erro na requisição:", err);
}
})
.finally(() => {
this.cancelSource = null; // Limpa o token após a requisição/cancelamento
});
},
cancelarBusca() {
if (this.cancelSource) {
this.cancelSource.cancel("Operação de busca cancelada pelo usuário.");
}
}
}
};
</script>
Encapsulamento de Instâncias Axios
Encapsular o Axios em um módulo ou função facilita a gestão de configurações, interceptadores e erros. Isso promove reutilização de código, manutenibilidade e flexibilidade, caso seja necessário trocar a biblioteca HTTP no futuro.
// services/httpService.js
import axios from 'axios';
export function criarClienteHTTP(configuracaoInicial) {
// 1. Cria uma nova instância Axios com configurações base
const instancia = axios.create({
baseURL: configuracaoInicial.baseURL || "http://localhost:8080/api",
timeout: configuracaoInicial.timeout || 8000,
headers: {
'Content-Type': 'application/json',
...configuracaoInicial.headers // Mescla cabeçalhos adicionais
}
});
// 2. Adiciona interceptadores de requisição
instancia.interceptors.request.use(
config => {
// Exemplo: Adicionar token de autenticação, se disponível
const token = localStorage.getItem('jwtToken');
if (token) {
config.headers.Authorization = `Bearer ${token}`;
}
// Exemplo: Mostrar um indicador de carregamento
// mostrarSpinnerGlobal();
return config;
},
error => {
// Lidar com erros na fase de envio da requisição
console.error("Erro no interceptador de requisição:", error);
// ocultarSpinnerGlobal();
return Promise.reject(error);
}
);
// 3. Adiciona interceptadores de resposta
instancia.interceptors.response.use(
response => {
// Exemplo: Ocultar o indicador de carregamento
// ocultarSpinnerGlobal();
return response; // Retorne a resposta completa ou apenas os dados (response.data)
},
error => {
// Lidar com erros de resposta HTTP
console.error("Erro no interceptador de resposta:", error.response);
// ocultarSpinnerGlobal();
if (error.response) {
const { status, data } = error.response;
if (status === 401) {
console.log("Sessão expirada ou não autorizada. Redirecionando...");
// window.location.href = '/login';
} else if (status === 404) {
console.log("Recurso não encontrado.");
} else {
console.log(`Erro no servidor: ${status} - ${data.message || 'Erro desconhecido'}`);
}
} else if (error.request) {
// A requisição foi feita, mas não houve resposta (rede offline, CORS, etc.)
console.error("Nenhuma resposta recebida do servidor.");
} else {
// Algo aconteceu na configuração da requisição que disparou um erro
console.error("Erro ao configurar requisição:", error.message);
}
return Promise.reject(error);
}
);
// 4. Retorna a instância configurada
return instancia;
}
// Exemplo de uso em outro arquivo:
// import { criarClienteHTTP } from './services/httpService';
// const clienteAPI = criarClienteHTTP({ baseURL: 'https://minhaapi.com/v1' });
// clienteAPI.get('/usuarios').then(res => console.log(res.data));
Este padrão garante que todas as requisições feitas através de instancia herdem as configurações e interceptadores definidos, enquanto permite flexibilidade para ajustes específicos por chamada.
Gerenciamento de Tokens de Autenticação
Ao lidar com rotas protegidas por autenticação (como JWT), o interceptador de requisição é o local ideal para adicionar o token ao cabeçalho Authorization.
// Exemplo de instância para rotas que exigem autenticação
let clienteAutenticado = axios.create({});
clienteAutenticado.interceptors.request.use(config => {
const token = obterTokenDeAutenticacao(); // Função para buscar o token (ex: localStorage)
if (token) {
config.headers.Authorization = `Bearer ${token}`;
}
return config;
}, error => {
return Promise.reject(error);
});
// Para rotas públicas, use outra instância ou o Axios padrão sem este interceptador.
let clientePublico = axios.create({});
Integração com Animações de Carregamento (Loading)
Interceptors também são excelentes para exibir e ocultar indicadores de carregamento durante as requisições.
let clienteComLoading = axios.create({});
// Interceptador de Requisição: mostra o spinner
clienteComLoading.interceptors.request.use(config => {
mostrarSpinnerDeCarregamento(); // Função que exibe seu spinner
return config;
}, error => {
ocultarSpinnerDeCarregamento(); // Garante que o spinner seja ocultado mesmo em erro pré-envio
return Promise.reject(error);
});
// Interceptador de Resposta: oculta o spinner
clienteComLoading.interceptors.response.use(response => {
ocultarSpinnerDeCarregamento(); // Oculta o spinner ao receber uma resposta
return response;
}, error => {
ocultarSpinnerDeCarregamento(); // Oculta o spinner em caso de erro na resposta
return Promise.reject(error);
});
function mostrarSpinnerDeCarregamento() {
console.log("Mostrando spinner de carregamento...");
// Lógica real para exibir o spinner no DOM
}
function ocultarSpinnerDeCarregamento() {
console.log("Ocultando spinner de carregamento...");
// Lógica real para ocultar o spinner no DOM
}