Ravakahn Gladior
Ravakahn Gladior Ravakahn foi um gladiador que, na Roma Antiga, lutava com outros gladiadores ou animais, às vezes, até a morte, para o entretenimento do público romano. há 4 anos

Comparando diferentes formas para fazer requisições HTTP no Javascript em 2020

Comparando diferentes formas para fazer requisições HTTP no Javascript em 2020

Recentemente eu tive que decidir qual tecnologia iria utilizar em um grande projeto Javascript para fazer chamadas AJAX. Se você estiver usando JavaScript, terá diferentes maneiras de fazer requests ao server-side.

A alguns anos atras, já existia alguns meio para extrair dados de um servidor sem a necessidade de atualização de página, mas eles geralmente contavam com técnicas estranhas. A Microsoft desenvolveu o XMLHttpRequest como uma alternativa de navegação para o seu leitor de emails Outlook, e só se tornou um padrão da web em 2006.

A Fetch API foi introduzida em 2015 com o ES6. As interfaces genéricas de Request e Response fornecem consistência, enquanto as Promises permite o encadeamento fácil sem a utilização de callbacks. O Fetch é limpo, elegante e simples de entender, mas existem outras boas alternativas e as veremos brevemente neste artigo.

Para simplificar, vou me concentrar no que são, suas sintaxes e alguns prós e contras de cada alternativa.

  • XMLHttpRequest
  • JQuery.ajax
  • Qwest
  • SuperAgent
  • Http-client
  • Axios
  • Fetch
  • \<Request> Este está obsoleto e não será abordado

A seguir mostro os exemplos básicos de Requests GET e POST usando diferentes alternativas. Vamos começar então.

Sumário

XMLHttpRequest

O objeto XMLHttpRequest pode ser usado para requisitar dados de um servidor da web. É o método mais antigo dessa comparação e, embora outras opções o superem, ainda é válido e útil por sua compatibilidade com versões anteriores e maturidade.

GET

var req = new XMLHttpRequest();
// A propriedade onreadystatechange especifica uma function
// que sera invocada toda vez que o status
// de XMLHttpRequest altera
req.onreadystatechange = function() {
  // this.readyState = 4 significa concluido
  if (this.readyState == 4 && this.status == 200) {
    // responseText contem uma string
    console.log(xhttp.responseText)
    // faca alguma coisa
  }
};
req.open("GET", '/url', true);
req.send();

POST

var formData = new FormData();
formData.append("email", "email@email.com");
var req = new XMLHttpRequest();
req.onreadystatechange = function() {}
req.open("POST", '/url');
req.send(formData);

Pros

  • Funciona na maioria dos navegadores;
  • É uma API nativa nos navegadores;
  • Não é necessário carregar bibliotecas;
  • Compatibilidade com versões antigas de navegadores;
  • Maduro/estável.

Contras

  • Sintaxe verbosa;
  • Utiliza callback (callback hell);
  • É substituido nativamente pelo Fetch API.

Referências

JQuery.ajax

O JQuery é uma biblioteca amplamente usada até pouco tempo atrás e permitia requisições assíncronas de HTTP (AJAX).

Todos os métodos Ajax do jQuery retornam um superconjunto do objeto XMLHTTPRequest

GET

$.ajax({
    url: '/url'
  }).done(function(data) {
    // todo
  }).fail(function() {
    // error handler
});

POST

$.ajax({
  type: "POST",
  url: '/url',
  data: data,
  success: successCallBack,
  error: errorCallBack,
  dataType: dataType
});

Pros

  • Suporte e documentação de ótima qualidade;
  • Objeto configurável;
  • JQuery está em vários projetos;
  • Baixa curva de aprendizado;
  • Você pode abortar a requisição porquê retorna um objeto XMLHttpRequest.

Contras

  • Não é nativo;
  • É necessário carregar o JQuery;
  • Todas as funcionalidade do JQuery são adicionadas, não somente as necessárias para fazer as requests em AJAX.

Referências

Qwest

Qwest is a simple ajax library based on promises, and that supports XmlHttpRequest2 unique data like ArrayBuffer, Blob, and FormData.

GET

qwest.get('/url')
.then(function(xhr, response) {
  // fazer algo com os dados
});

POST

qwest.post('/url', {
  email: 'email@email.com',
  idade: 30
})
.then(function(xhr, response) {
  // fazer alguma coisa
})
.catch(function(e, xhr, response) {
  // processar o erro
});

Pros

  • Você pode estabelecer um limite de requests;
  • Baseado em Promises.

Contras

  • XmlHttpRequest2 não está disponível em todos os navegadores;
  • Não é nativo;
  • Necessário carregá-lo de uma fonte externa.

Referências

SuperAgent

SuperAgent é uma API ajax criada para flexibilidade, legibilidade e com uma baixa curva de aprendizado. Também funciona com o Node.js.

GET

request('GET', '/url')
  .then(success, failure);

O método query() aceita objetos que, quando usados com o método GET, formarão uma query string. No exemplo a seguir será produzido a URL /url?name=bob&lastName=oliver&order=desc.

request
   .get('/url')
   .query({ name: 'bob' })
   .query({ lastname: 'oliver' })
   .query({ order: 'desc' })
   .then(res => {
     console.log(res)
   });

POST

request
  .post('/url')
  .send({ name: 'bob' })
  .set('Accept', 'application/json')
  .then(res => {
    console.log('result' + JSON.stringify(res.body));
  });

Pros

  • Baseado em Promises;
  • Funciona no navegador e no Node.js;
  • Para abortar uma request, use o método request.abort();
  • Bem conhecido pela comunidade;
  • Interface perfeita para fazer solicitações HTTP;
  • Suporte a retry requests quando houver uma falha.

Contras

  • Não suporta o monitoramento do progresso como no XMLHttpRequest;
  • Não é nativo;
  • Necessário carregá-lo de uma fonte externa.

Referências

Http-client

Http-client permite você compor requisições HTTP utilizando a API Javascript Fetch.

GET

//using ES6 modules
import { createFetch, base, accept, parse } from 'http-client'
const fetch = createFetch(
  base('/url'),
  accept('application/json'),
  parse('json')
)
fetch('/url').then(response => {
  console.log(response.jsonData)
})

POST

//using ES6 modules
import { createFetch, method, params } from 'http-client'
const fetch = createFetch(
  params({ email: 'email@email.com' }),
  base('/url')
)

Pros

  • Funciona no navegador e no Node.js;
  • Pode ser utilizado em Service Workers;
  • Baseado Promises;
  • Fornece guardas de cabeçalho (header guard).

Contras

  • Não é nativo;
  • Necessário carregá-lo de uma fonte externa.

Referências

Axios

Biblioteca HTTP baseada em Promises para realizar HTTP requests no navegador e Node.js.

GET

axios({
  url: '/url',
  method: 'get'
})

POST

axios.post('/url', {
    email: 'email@email.com'
  })
  .then(function (response) {
    console.log(response);
  })
  .catch(function (error) {
    console.log(error);
  });

Pros

  • Usa promessas para evitar o callback hell;
  • Funciona no navegador e no Node.js;
  • Suporta verificação do progresso do upload;
  • Pode definir o tempo limite de resposta;
  • Configuração das solicitações passando um objeto de configuração;
  • Implementado a proposta de promise cancelável;
  • Converte automaticamente os dados em JSON.

Contras

  • Não é nativo;
  • Necessário carregá-lo de uma fonte externa.

Referências

Fetch

Fetch é uma API nativa dos navegadores para fazer requests pela rede mundial e substitui nativamente o XMLHttpRequest. Esta API utiliza Promises, o que evita o callback hell causado pelo uso do XMLHttpRequest.

GET

//With ES6 fetch
fetch('/url')
  .then(data => {
    // ...do some stuff whith data
  }).catch(error => {
    // Handle error
});

POST

fetch('/url', {
  method: 'post',
  headers: {
    'Accept': 'application/json, text/plain, */*',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({name: 'Murdock'})
}).then(res=>res.json())
  .then(res => console.log(res));

// ou com ES2017
(async () => {

  const response = await fetch('/url', {
    method: 'POST',
    headers: {
      'Accept': 'application/json',
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({name:'Cooper'})
  });

  const result = await response.json();
  console.log(result);

})();

Pros

  • É uma API nativa do navegador;
  • O Fetch é basicamente um XMLHttpRequest + Promises;
  • Não é necessário carregá-lo de uma fonte externa;
  • Usa Promises para evitar o callback hell;
  • Não há necessidade de mais dependências;
  • É amigável e fácil de aprender;
  • É compatível na maioria dos navegadores usados recentemente;
  • É a substituição natural do objeto XMLHttpRequest nativo;
  • Baixa curva de aprendizado.

Contras

  • O processo natural de duas etapas ao manipular dados JSON. O primeiro é fazer a requisição e o segundo é chamar o método .json(). No Axios, você obtém o objeto JSON por padrão;
  • A Promise retornada pelo Fetch rejeita apenas em caso de falha na rede ou se alguma coisa impedir a conclusão da solicitação. A Promise não será rejeitada em casos que a resposta seja HTTP 404 ou 500;
  • Faltam alguns recursos úteis de outras bibliotecas, como por exemplo: cancelamento de requisições;
  • A busca não envia ou recebe por padrão cookies do servidor, resultando em solicitações não autenticadas se o site depender da manutenção de uma sessão do usuário. Mas você pode ativar adicionando: { credentials: 'same-origin' }.

Referências

Conclusão

Fetch API é um novo padrão e é suportado pelas novas versões do Chrome e Firefox sem usar nenhuma biblioteca adicional.

Recomenda-se dedicar algum tempo para examinar as características do Axios, SuperAgent ou o restante das bibliotecas, pois todas possuem documentação adequada, são fáceis de usar e sua curva de aprendizado não é muito grande. Para algumas situações, elas oferecem recursos que o Fetch API não oferece.

No meu caso, prefiro o Fetch porque não preciso de recursos especiais, e o Fetch é nativo no JavaScript e suficiente para a maioria dos projetos.