Voltar ao blogue
Guias
Sorin-Gabriel MaricaLast updated on Mar 31, 20268 min read

Aprenda a usar o Node-Fetch do NPM para fazer pedidos HTTP no Node.js

Aprenda a usar o Node-Fetch do NPM para fazer pedidos HTTP no Node.js

A realização de pedidos HTTP é uma das funcionalidades mais importantes de qualquer linguagem de programação moderna. O Node.js não é exceção a esta regra, mas até agora esta funcionalidade estava nas mãos de demasiados pacotes npm disponíveis no mercado. O Node-Fetch oferece uma alternativa a esta situação, utilizando a API fetch original, atualmente suportada pela maioria dos navegadores existentes.

Introdução à API Node-Fetch

Antes de começar a falar sobre a API Node-Fetch, devo dar-lhe uma breve informação sobre o que é uma solicitação HTTP. O objetivo de uma solicitação HTTP é recuperar informações de URLs em toda a Internet. Um exemplo simples de uma solicitação HTTP é aceder a um site.

Enquanto há muito tempo as solicitações HTTP eram feitas utilizando XMLHttpRequest ou objetos XHR, hoje em dia todos os navegadores modernos suportam a API Fetch do JavaScript. Isto permite aos programadores fazer as solicitações com uma sintaxe muito mais simples e limpa. No entanto, a API Fetch esteve ausente durante muito tempo da linguagem do lado do servidor Node.JS, deixando espaço para outros pacotes personalizados cuidarem desta funcionalidade, tais como: Axios, GOT e muitos outros.

O Node-Fetch é o equivalente à API Fetch do JavaScript e agora está finalmente disponível também no Node.JS.

Pré-requisitos para utilizar a API Node-Fetch

Em primeiro lugar, uma vez que este é um tutorial sobre o Node.JS, terá, naturalmente, de ter o Node.JS instalado. Se ainda não o tiver, pode descarregá-lo e instalá-lo a partir deste link.

O Node.js lançou suporte experimental para a API Fetch apenas a partir da versão 17.5. Por isso, precisará de ter, pelo menos, a versão 17.5 do Node. Além disso, terá de utilizar o sinalizador –experimental-fetch ao executar os seus scripts.

Se tiver uma versão mais antiga do Node.JS, para atualizar para a versão mais recente pode usar o pacote n. O n é um pacote npmjs cujo único objetivo é permitir-lhe alternar entre as versões do Node e do npm. Para o instalar e atualizar para a versão mais recente, siga estes passos:

npm install -g n
n latest

O comando n latest instalará a versão mais recente do Node.js. Para verificar a sua versão do Node.js, basta executar este comando:

node –version

Como utilizar o Node-Fetch

Fazer uma solicitação HTTP em qualquer linguagem de programação é uma operação assíncrona, uma vez que receber a resposta da solicitação leva tempo. Existem duas abordagens no que diz respeito à forma como pode utilizar operações assíncronas. Pode optar por esperar pela resposta e, em seguida, continuar com o seu código, ou executar o seu código em paralelo.

O Node-Fetch suporta chamadas de função síncronas e assíncronas.

Pedidos GET no Node-Fetch

Para fazer uma solicitação GET simples e extrair o corpo da resposta, pode usar o trecho de código abaixo:

fetch('https://www.webscrapingapi.com/')

    .then((response) => response.text())

    .then((body) => {

        console.log(body);

    });

Para executar este código, deve guardá-lo num ficheiro chamado node-fetch-example.js e executá-lo a partir da mesma pasta utilizando este comando: node --experimental-fetch node-fetch-example.js. Note que, ao executá-lo, receberá um aviso a indicar que «A API Fetch é uma funcionalidade experimental». Isto é normal, uma vez que se trata de uma funcionalidade experimental à data da redação deste artigo.

O trecho de código anterior não espera que a solicitação termine antes de continuar a sua execução. Isto significa que qualquer código abaixo deste começará a ser executado imediatamente, sem esperar que o fetch termine. Por exemplo, se adicionar um console.log(“Something”); abaixo do código, ao executar o script, a saída ficará assim:

Para explicar melhor o código acima, poderá notar que usamos a função “then” duas vezes. O primeiro “then” será executado quando recebermos uma resposta da solicitação HTTP, e o que ele faz é mapear essa resposta com o conteúdo do método response.text() (que retorna o corpo da resposta). No entanto, o método response.text() também é assíncrono e, por isso, precisamos de aguardar a sua resposta no segundo “then”, onde body é igual ao resultado da promessa de response.text().

Também pode chamar a API fetch usando await, tal como fazemos no exemplo seguinte:

(async () => {

    const response = await fetch('https://webscrapingapi.com');

    const body = await response.text();

    console.log(body);

})();

Isto dá uma explicação ainda melhor sobre como a API fetch funciona e quais são as promessas pelas quais precisa de esperar. Mais adiante neste artigo, iremos utilizar a API fetch com await, uma vez que isto nos permite manter uma sintaxe mais limpa para o código.

Enviar cabeçalhos para a solicitação

Outra funcionalidade de que irá precisar ao enviar pedidos é a capacidade de definir os cabeçalhos do pedido que está a fazer. Para tal, pode adicionar os cabeçalhos no segundo parâmetro da API fetch, da seguinte forma:

(async () => {

    const response = await fetch('http://httpbin.org/headers', {

        headers: {

            'my-custom-header': 'my-header-value'

        }

    });

    const body = await response.text();

    console.log(body);

})();

Além dos cabeçalhos, existem muitas outras opções que pode enviar no segundo parâmetro da API fetch. Para ver todas elas, consulte a documentação da API fetch (a utilizada no lado do cliente).

Pedidos POST no Node-Fetch

Outra opção importante da API fetch é a opção method. Esta especifica o método que está a utilizar para a solicitação HTTP. Existem 5 métodos que pode utilizar: GET, POST, PUT, PATCH e DELETE, mas, destes, os dois primeiros são os mais utilizados (GET e POST). Por predefinição, se nenhum método for especificado, o Node-Fetch utilizará GET.

Para fazer uma solicitação POST usando o Node-Fetch, pode usar este trecho de código:

(async () => {

    const response = await fetch('http://httpbin.org/post', {

        method: 'POST',

        body: JSON.stringify({

            'key': 'value'

        })

    });

    const body = await response.text();

    console.log(body);

})();

O que poderá notar aqui é que usamos JSON.stringify para enviar o corpo da solicitação. Isto porque a API fetch envia o corpo como uma string em vez de um objeto, ao contrário de outros pacotes, como o axios.

A API fetch também abrange todos os outros métodos de solicitação.

Tratamento de erros no Node-Fetch

O tratamento de erros ao efetuar pedidos HTTP é imprescindível, uma vez que nunca se pode contar com a disponibilidade constante de um serviço de terceiros. Como boa prática, deve sempre tratar os erros, para evitar que a sua aplicação ou script deixe de funcionar juntamente com o URL para o qual está a efetuar o pedido.

O tratamento de erros no Node-Fetch pode ser feito envolvendo o código com uma sintaxe simples de try-catch. Aqui está um exemplo de como fazer isso ao usar await:

(async () => {

    try {

        const response = await fetch('[INVALID_URL]');

        const responseBody = await response.text();

    } catch (error) {

        console.log(error.message);

    }

})();

Se preferir usar o fetch sem o await, pode adicionar um catch ao seu código da seguinte forma:

fetch('[INVALID_URL]')

    .then((response) => response.text())

    .then((body) => {

        console.log(body);

    })

    .catch((error) => {

        console.log(error.message);

    });

Casos de utilização do Node-Fetch

Fazer pedidos HTTP pode ser útil de muitas formas, uma vez que permite obter novas informações de diferentes serviços e extrair dados de uma forma bastante elegante e fácil. Existem alguns casos de utilização para isto que iremos explorar nos parágrafos seguintes.

Utilizar o Node-Fetch para pedidos de API

Ao programar, muitas vezes pode ser necessário utilizar uma API. A razão para isso é que pode ser necessário obter dados específicos de uma fonte de backend diferente e, em seguida, processá-los ou atualizá-los. Um bom exemplo aqui seria uma API com 4 endpoints que permite criar, ler, atualizar e eliminar utilizadores (operações CRUD) numa base de dados de backend a partir de outro servidor.

Muitas vezes, uma API deste tipo necessitaria de autenticação para impedir que fontes não autorizadas a utilizassem e alterassem os dados em seu benefício. As solicitações HTTP têm muitos métodos de autenticação. Um dos mais comuns é a utilização de uma chave de API, em que o fornecedor da API lhe dá uma chave que só você deve conhecer, e os pontos finais da API só funcionam quando se envia a chave correta.

Outro método através do qual uma API pode ser protegida é a Autenticação Básica. Isto significa que, para aceder à API, terá de enviar um cabeçalho com uma cadeia codificada em base64 no formato “username:password”. Aqui está um exemplo de como pode utilizar a autenticação básica numa solicitação POST:

(async () => {

    const response = await fetch('http://httpbin.org/post', {

        method: 'POST',

        headers: {

            "Authorization": `Basic ${btoa('login:password')}`

        },

        body: JSON.stringify({

            'key': 'value'

        })

    });

    const body = await response.text();

    console.log(body);

})();

Use o Node-Fetch para Web Scraping

O Web Scraping é uma forma de obter conteúdo de sites e analisá-lo, para que fique apenas com os dados necessários, que pode utilizar como desejar. Uma boa biblioteca npmjs que pode utilizar para facilitar a análise dos dados é o cheerio. Esta biblioteca permite-lhe consultar html estático, uma vez obtido da API fetch, da mesma forma que o faria a partir de javascript ou jquery.

Eis um exemplo de como obter o título de uma página utilizando a API fetch e o cheerio:

const cheerio = require("cheerio");

(async () => {

    const response = await fetch('https://www.webscrapingapi.com/');

    const responseBody = await response.text();

    const $ = cheerio.load(responseBody);

    console.log($('title').first().text());

})();

O exemplo acima deve devolver “WebScrapingAPI | All-In-One Scraping API”, uma vez que este é o título da página (o texto escrito na parte superior da janela do seu navegador). Para explicar melhor, usamos o fetch para obter o código-fonte da página HTML de https://www.webscrapingapi.com/ e usamos o cheerio para analisar esse conteúdo. Para saber mais sobre o cheerio, pode consultar a documentação aqui 

Extrair informações de outros sites pode ser útil de várias maneiras. Por exemplo, as informações extraídas podem ser usadas para criar um conjunto de dados de treino para um modelo de aprendizagem automática ou para criar uma ferramenta de comparação de preços que extrai dados de várias fontes e depois os compara.

Embora o exemplo acima funcione bem, a API fetch pode nem sempre ser a melhor opção quando se trata de scraping. Isto porque os sites modernos hoje em dia exibem o seu conteúdo através de JavaScript e utilizam captchas ou outros métodos para impedir que os seus dados sejam extraídos. A API fetch funciona como um simples CURL para o URL fornecido e recupera o conteúdo estático que a página exibe quando é carregada, sem qualquer renderização de JavaScript.

Para extrair dados e, ao mesmo tempo, executar o código JavaScript na página, poderá querer explorar alternativas como o Puppeteer, conforme descrito neste artigo sobre extração avançada. Se, no entanto, não quiser passar por todo este trabalho, pode utilizar a WebScrapingAPI, uma API criada especialmente para esta tarefa, que trata de todos estes problemas (incluindo deteções antibot) e que inclui um período de teste gratuito com todas as funcionalidades incluídas. 

Resumo

Em resumo, a boa notícia é que a tão esperada API fetch está finalmente disponível no Node.js, embora, por enquanto, esteja apenas na fase de funcionalidade experimental (à data da redação deste artigo). Embora já fosse possível fazer pedidos no Node.js anteriormente, a única forma de o fazer era através dos objetos XMLHttpRequest/XHR ou de um dos muitos pacotes disponíveis, como o Axios ou o GOT.

Esta mudança tornará o JavaScript do lado do cliente e o Node.js do lado do servidor mais semelhantes, uma vez que esta funcionalidade já estava disponível e era suportada por todos os navegadores modernos no JavaScript do lado do cliente.

Fazer pedidos HTTP pode ser útil de várias formas, como utilizar uma API ou extrair dados de um site. Embora os outros pacotes npm continuem a ser uma opção e continuem a ser utilizados em projetos antigos, utilizar o fetch é a melhor solução para o futuro. Isto irá melhorar a legibilidade do código Node.js e tornará a transição do front-end para o back-end ainda mais fácil.

Sobre o autor
Sorin-Gabriel Marica, Desenvolvedor Full-Stack @ WebScrapingAPI
Sorin-Gabriel MaricaDesenvolvedor Full-Stack

Sorin Marica é engenheiro Full Stack e DevOps na WebScrapingAPI, onde desenvolve funcionalidades do produto e mantém a infraestrutura que garante o bom funcionamento da plataforma.

Comece a construir

Pronto para expandir a sua recolha de dados?

Junte-se a mais de 2.000 empresas que utilizam a WebScrapingAPI para extrair dados da Web à escala empresarial, sem quaisquer custos de infraestrutura.