Fundamentos do Node.js
Consumindo APIs Externas com Node.js (Fetch API ou Módulos HTTP)
Aprenda sobre consumindo apis externas com node.js (fetch api ou módulos http)
Consumindo APIs Externas com Node.js
Olá, devs! 👋 Nesta aula prática, vamos mergulhar no mundo da comunicação entre aplicações, aprendendo a consumir APIs externas usando Node.js. Isso é fundamental para qualquer aplicação moderna que precise interagir com serviços de terceiros, buscar dados ou enviar informações.
Vamos explorar duas abordagens principais: a moderna Fetch API (nativa no Node.js a partir da versão 18) e os módulos HTTP/HTTPS built-in do Node.js.
1. Introdução: O que é uma API e por que consumi-la?
Uma API (Application Programming Interface) é um conjunto de regras e definições que permite que diferentes softwares se comuniquem entre si. Pense nela como um "garçom" que leva seu pedido (requisição) para a cozinha (servidor) e traz a comida (resposta) de volta para você.
Por que consumimos APIs externas?
- Acesso a dados: Obter informações de bases de dados de terceiros (previsão do tempo, cotações de moedas, dados de usuários, etc.).
- Funcionalidades: Utilizar serviços especializados (processamento de pagamentos, envio de e-mails, autenticação, mapas).
- Integração: Conectar sua aplicação com outras plataformas ou sistemas.
Nesta aula, focaremos em como sua aplicação Node.js pode ser o "cliente" que faz requisições a essas APIs.
2. Consumindo APIs com Node.js
Temos algumas opções para fazer requisições HTTP em Node.js. Vamos focar nas soluções nativas: a Fetch API e os módulos http/https.
2.1. Abordagem 1: Fetch API (Recomendada para Node.js 18+)
A Fetch API é uma interface moderna e baseada em Promises para fazer requisições de rede. Ela foi originalmente criada para navegadores, mas foi integrada nativamente ao Node.js a partir da versão 18, tornando-a uma excelente escolha para novas aplicações.
Vantagens:
- Moderna e Promise-based: Facilita o trabalho com código assíncrono (especialmente com
async/await). - Padrão web: Consistente com a forma como as requisições são feitas em navegadores.
- Simples para GET: Requisições GET são muito concisas.
Documentação Oficial:
- MDN Web Docs: Fetch API
- Node.js Docs: fetch (experimental) (Note: No Node.js 18+, já não é experimental)
Exemplo 1: Requisição GET Simples com Fetch API
Vamos buscar informações sobre usuários de uma API de testes gratuita, a JSONPlaceholder.
// app.js
async function getUsers() {
try {
const response = await fetch('https://jsonplaceholder.typicode.com/users');
// Verifica se a resposta foi bem-sucedida (status 2xx)
if (!response.ok) {
throw new Error(`Erro HTTP! Status: ${response.status}`);
}
const users = await response.json();
console.log('Usuários obtidos com Fetch API:');
users.forEach(user => console.log(`- ${user.name} (${user.email})`));
} catch (error) {
console.error('Erro ao buscar usuários com Fetch API:', error.message);
}
}
getUsers();Para executar este código, salve-o como app.js e execute no terminal:
node app.jsVocê verá uma lista de usuários no console.
Exemplo 2: Requisição POST com Fetch API
Agora, vamos tentar criar um novo "post" na mesma API.
// app.js (continuação ou novo arquivo)
async function createPost() {
const newPost = {
title: 'Meu Primeiro Post com Fetch API',
body: 'Este é o conteúdo do meu post, enviado via Node.js.',
userId: 1,
};
try {
const response = await fetch('https://jsonplaceholder.typicode.com/posts', {
method: 'POST', // Define o método como POST
headers: {
'Content-Type': 'application/json', // Informa que estamos enviando JSON
},
body: JSON.stringify(newPost), // Converte o objeto JavaScript para JSON string
});
if (!response.ok) {
throw new Error(`Erro HTTP! Status: ${response.status}`);
}
const createdPost = await response.json();
console.log('\nPost criado com Fetch API:');
console.log(createdPost);
} catch (error) {
console.error('Erro ao criar post com Fetch API:', error.message);
}
}
// Chame a função para criar o post
createPost();2.2. Abordagem 2: Módulos HTTP/HTTPS do Node.js
Os módulos http e https são módulos core do Node.js, o que significa que eles vêm embutidos e não precisam ser instalados. Eles fornecem uma API de baixo nível para fazer requisições HTTP e HTTPS, respectivamente.
Vantagens:
- Nativos: Sempre disponíveis, sem dependências externas.
- Controle total: Permitem um controle mais granular sobre a requisição.
- Essenciais para versões antigas do Node.js: Se você estiver em um ambiente Node.js < 18, esta é a forma nativa de fazer requisições.
Desvantagens:
- Mais verboso: Requer mais código para tarefas comuns em comparação com
fetchou bibliotecas de terceiros. - Baseado em callbacks/eventos: Pode ser um pouco mais complexo de gerenciar com
async/awaitsem promisificar.
Documentação Oficial:
Exemplo 3: Requisição GET Simples com Módulo HTTPS
Vamos buscar os mesmos usuários, mas agora usando o módulo https.
// app.js (continuação ou novo arquivo)
const https = require('https'); // Importa o módulo https
function getUsersWithHttps() {
https.get('https://jsonplaceholder.typicode.com/users', (res) => {
let data = '';
// Um chunk de dados foi recebido.
res.on('data', (chunk) => {
data += chunk;
});
// A resposta completa foi recebida.
res.on('end', () => {
try {
const users = JSON.parse(data);
console.log('\nUsuários obtidos com Módulo HTTPS:');
users.forEach(user => console.log(`- ${user.name} (${user.email})`));
} catch (e) {
console.error('Erro ao parsear JSON:', e.message);
}
});
}).on('error', (err) => {
console.error('Erro ao buscar usuários com Módulo HTTPS:', err.message);
});
}
getUsersWithHttps();Exemplo 4: Requisição POST com Módulo HTTPS
Criando um post com o módulo https. Note que é um pouco mais complexo, pois precisamos criar um objeto options e usar req.write() e req.end().
// app.js (continuação ou novo arquivo)
const https = require('https');
function createPostWithHttps() {
const postData = JSON.stringify({
title: 'Meu Segundo Post com Módulo HTTPS',
body: 'Este é o conteúdo do meu post, enviado via módulo HTTPS.',
userId: 1,
});
const options = {
hostname: 'jsonplaceholder.typicode.com',
port: 443, // Porta padrão para HTTPS
path: '/posts',
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Content-Length': Buffer.byteLength(postData), // Importante para POST
},
};
const req = https.request(options, (res) => {
let data = '';
res.on('data', (chunk) => {
data += chunk;
});
res.on('end', () => {
try {
const createdPost = JSON.parse(data);
console.log('\nPost criado com Módulo HTTPS:');
console.log(createdPost);
} catch (e) {
console.error('Erro ao parsear JSON:', e.message);
}
});
});
req.on('error', (err) => {
console.error('Erro ao criar post com Módulo HTTPS:', err.message);
});
// Envia os dados do post
req.write(postData);
req.end(); // Finaliza a requisição
}
createPostWithHttps();2.3. Comparação e Escolha ⚖️
| Característica | Fetch API (Node.js 18+) | Módulos HTTP/HTTPS |
|---|---|---|
| Sintaxe | Moderna, Promise-based (async/await friendly) | Baseada em callbacks/eventos, mais verbosa |
| Nível | Mais alto nível, abstrai detalhes da rede | Mais baixo nível, controle granular |
| Disponibilidade | Nativa no Node.js 18+, via node-fetch para versões < 18 | Nativa em todas as versões do Node.js |
| Uso comum | Requisições RESTful, APIs modernas | Requisições de baixo nível, proxies, servidores HTTP/HTTPS |
| Tratamento de Erros | try/catch com await response.ok | Eventos 'error' e verificação de res.statusCode |
Recomendação: Para a maioria dos casos em Node.js 18+, a Fetch API é a escolha mais moderna e fácil de usar. Se você precisa de controle muito granular ou está trabalhando com uma versão mais antiga do Node.js, os módulos http/https são a opção nativa.
3. Exercícios Práticos: Mão na Massa! 🚀
Vamos aplicar o que aprendemos consumindo a API pública do Cat Facts (https://catfact.ninja/).
Configuração Inicial
Crie um novo arquivo exercicios.js.
Tarefas:
-
Tarefa 1: Buscar um Fato Aleatório de Gato (GET com Fetch API)
- Crie uma função assíncrona chamada
getCatFactFetch(). - Dentro dela, use
fetchpara fazer uma requisição GET parahttps://catfact.ninja/fact. - Converta a resposta para JSON.
- Imprima o fato do gato no console.
- Implemente tratamento de erros usando
try/catche verificandoresponse.ok.
- Crie uma função assíncrona chamada
-
Tarefa 2: Buscar 5 Fatos de Gato (GET com Módulo HTTPS)
- Crie uma função chamada
getMultipleCatFactsHttps(count). - Use o módulo
httpspara fazer uma requisição GET parahttps://catfact.ninja/facts?limit=5. - Colete os chunks de dados e faça o parse do JSON.
- Imprima cada fato de gato da lista no console.
- Implemente tratamento de erros usando o evento
'error'da requisição.
- Crie uma função chamada
-
Tarefa 3 (Desafio): Consumir e Exibir Dados Formatados
- Escolha uma API pública de sua preferência (ex: Star Wars API (SWAPI), PokéAPI, Random User API).
- Crie uma função (usando
fetchouhttps, sua escolha) que:- Faça uma requisição GET para um endpoint específico.
- Exiba os dados de forma formatada e legível no console (ex: se for a SWAPI, liste o nome do personagem, altura e cor do cabelo).
- Inclua tratamento de erros robusto.
// exercicios.js
// Tarefa 1: Buscar um Fato Aleatório de Gato (GET com Fetch API)
async function getCatFactFetch() {
console.log('--- Tarefa 1: Fato de Gato com Fetch API ---');
try {
const response = await fetch('https://catfact.ninja/fact');
if (!response.ok) {
throw new Error(`Erro HTTP! Status: ${response.status}`);
}
const data = await response.json();
console.log('Fato de Gato:', data.fact);
} catch (error) {
console.error('Erro ao buscar fato de gato com Fetch API:', error.message);
}
}
// Tarefa 2: Buscar 5 Fatos de Gato (GET com Módulo HTTPS)
const https = require('https');
function getMultipleCatFactsHttps(count) {
console.log(`\n--- Tarefa 2: ${count} Fatos de Gato com Módulo HTTPS ---`);
https.get(`https://catfact.ninja/facts?limit=${count}`, (res) => {
let data = '';
res.on('data', (chunk) => {
data += chunk;
});
res.on('end', () => {
if (res.statusCode >= 200 && res.statusCode < 300) {
try {
const facts = JSON.parse(data);
console.log(`Fatos de Gato (${facts.data.length}):`);
facts.data.forEach((fact, index) => console.log(`${index + 1}. ${fact.fact}`));
} catch (e) {
console.error('Erro ao parsear JSON:', e.message);
}
} else {
console.error(`Erro HTTP! Status: ${res.statusCode}`);
}
});
}).on('error', (err) => {
console.error('Erro ao buscar fatos de gato com Módulo HTTPS:', err.message);
});
}
// Tarefa 3 (Desafio): Consumir e Exibir Dados Formatados (Exemplo com SWAPI)
async function getStarWarsCharacter(id) {
console.log(`\n--- Tarefa 3: Personagem Star Wars (ID: ${id}) com Fetch API ---`);
try {
const response = await fetch(`https://swapi.dev/api/people/${id}/`);
if (!response.ok) {
throw new Error(`Erro HTTP! Status: ${response.status}`);
}
const character = await response.json();
console.log('Personagem Encontrado:');
console.log(`Nome: ${character.name}`);
console.log(`Altura: ${character.height} cm`);
console.log(`Cor do Cabelo: ${character.hair_color}`);
console.log(`Planeta Natal: ${character.homeworld}`); // Nota: homeworld é uma URL, para obter o nome, seria outra requisição!
} catch (error) {
console.error('Erro ao buscar personagem Star Wars:', error.message);
}
}
// Chame suas funções para testar
(async () => {
await getCatFactFetch();
getMultipleCatFactsHttps(5);
await getStarWarsCharacter(1); // Luke Skywalker
await getStarWarsCharacter(10); // Obi-Wan Kenobi
})();
4. Resumo e Próximos Passos
Nesta aula, você aprendeu a:
- Compreender o que são APIs e por que as consumimos.
- Realizar requisições GET e POST usando a Fetch API (para Node.js 18+).
- Realizar requisições GET e POST usando os módulos HTTP/HTTPS nativos do Node.js.
- Implementar tratamento de erros básico para suas requisições.
Próximos Passos:
- Async/Await: Embora tenhamos usado
async/awaitcomfetch, aprofunde-se mais neste padrão para gerenciar código assíncrono de forma limpa. - Bibliotecas de Terceiros: Explore o
axios, uma biblioteca HTTP popular que oferece uma API mais rica e recursos como interceptores e cancelamento de requisições. - Tratamento de Erros Avançado: Implemente estratégias mais robustas para lidar com diferentes tipos de erros de rede e API (retries, timeouts, etc.).
- Construindo um Servidor: Na próxima aula, podemos usar o conhecimento de consumo de APIs para construir um servidor Node.js que serve dados obtidos de uma API externa! 🌐
Continue praticando e explorando diferentes APIs! A habilidade de integrar sua aplicação com serviços externos é um superpoder no desenvolvimento web. 💪