Las peticiones HTTP son una parte fundamental del desarrollo web moderno. Con la introducción de la API Fetch a Node.js, los desarrolladores ahora tienen una forma potente y consistente de realizar peticiones de red tanto en entornos de navegador como de servidor. En este tutorial completo, exploraremos cómo usar Node fetch de manera efectiva en tus proyectos.
¿Qué es la API Node Fetch y por qué deberías usarla?
La API Node fetch es un mecanismo moderno, basado en promesas, para realizar peticiones HTTP en aplicaciones Node.js. Originalmente una característica exclusiva del navegador, fetch se convirtió en una característica experimental en Node.js v18 y alcanzó la estabilidad en Node.js v21.
Beneficios clave de usar Node Fetch:
- Funcionalidad integrada: No es necesario instalar paquetes de terceros
- Basado en promesas: Sintaxis limpia y moderna con soporte para async/await
- Familiaridad multiplataforma: Misma API que fetch del lado del navegador
- Rendimiento mejorado: Construido sobre el cliente HTTP Undici de alto rendimiento
Probando tus peticiones de la API Node Fetch con herramientas modernas
Mientras aprendes a usar Node fetch, es esencial tener herramientas confiables para probar tus endpoints de API. Apidog destaca como la mejor alternativa a Postman para probar y documentar tus peticiones de la API Node fetch.

Como una plataforma de desarrollo de API todo en uno, Apidog combina la documentación de la API, las pruebas y los servidores mock en una única interfaz intuitiva.

Al desarrollar aplicaciones con Node fetch, Apidog te ayuda a visualizar las respuestas, colaborar con los miembros del equipo y asegurar que tus llamadas a la API estén funcionando correctamente antes de implementarlas en el código. Su capacidad para generar fragmentos de código para las peticiones de Node fetch hace que la transición de la prueba a la implementación sea fluida.

Configurando tu entorno para Node Fetch
Requisitos previos para usar Node Fetch
Antes de sumergirte en los ejemplos de Node fetch, asegúrate de tener:
- Node.js v18 o superior (preferiblemente v21+ para soporte estable de fetch)
- Comprueba tu versión de Node.js:
node -v
Compatibilidad de versiones de Node Fetch
- Node.js v21+: Fetch es estable y está listo para su uso en producción
- Node.js v18-v20: Fetch está disponible pero es experimental (usa el flag
-experimental-fetch
) - Versiones antiguas de Node.js: Instala el paquete
node-fetch
o actualiza Node.js
Si estás usando v18-v20, ejecuta tus aplicaciones con:
node --experimental-fetch app.js
Realizando tu primera petición Node Fetch
Comencemos con una petición GET básica usando Node fetch:
// Basic GET request with Node fetch
fetch('<https://api.example.com/data>')
.then(response => {
if (!response.ok) {
throw new Error(`HTTP error! Status: ${response.status}`);
}
return response.json(); // Parse JSON response
})
.then(data => {
console.log('Data received:', data);
})
.catch(error => {
console.error('Fetch error:', error);
});
Usando Node Fetch con Async/Await
Para un código más limpio, puedes usar async/await con Node fetch:
async function fetchData() {
try {
const response = await fetch('<https://api.example.com/data>');
if (!response.ok) {
throw new Error(`HTTP error! Status: ${response.status}`);
}
const data = await response.json();
console.log('Data received:', data);
return data;
} catch (error) {
console.error('Fetch error:', error);
}
}
// Call the function
fetchData();
Métodos de petición Node Fetch avanzados
Realizando peticiones POST con Node Fetch
async function postData(url, data) {
try {
const response = await fetch(url, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(data),
});
if (!response.ok) {
throw new Error(`HTTP error! Status: ${response.status}`);
}
return await response.json();
} catch (error) {
console.error('Fetch POST error:', error);
}
}
// Example usage
const newUser = {
name: 'John Doe',
email: 'john@example.com',
};
postData('<https://api.example.com/users>', newUser)
.then(data => console.log('User created:', data));
Peticiones PUT con Node Fetch
async function updateData(url, data) {
try {
const response = await fetch(url, {
method: 'PUT',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(data),
});
if (!response.ok) {
throw new Error(`HTTP error! Status: ${response.status}`);
}
return await response.json();
} catch (error) {
console.error('Fetch PUT error:', error);
}
}
// Example usage
const updatedUser = {
id: 1,
name: 'Jane Smith',
email: 'jane@example.com',
};
updateData('<https://api.example.com/users/1>', updatedUser)
.then(data => console.log('User updated:', data));
Peticiones DELETE con Node Fetch
async function deleteResource(url) {
try {
const response = await fetch(url, {
method: 'DELETE',
});
if (!response.ok) {
throw new Error(`HTTP error! Status: ${response.status}`);
}
// Some APIs return no content on DELETE
if (response.status === 204) {
return { success: true };
}
return await response.json();
} catch (error) {
console.error('Fetch DELETE error:', error);
}
}
// Example usage
deleteResource('<https://api.example.com/users/1>')
.then(result => console.log('Delete result:', result));
Manejando diferentes tipos de respuesta con Node Fetch
Node fetch puede trabajar con varios formatos de respuesta:
Manejo de respuestas JSON
fetch('<https://api.example.com/data>')
.then(response => response.json())
.then(data => console.log(data));
Manejo de respuestas de texto
fetch('<https://example.com/plain-text>')
.then(response => response.text())
.then(text => console.log(text));
Manejo de datos binarios
fetch('<https://example.com/image.png>')
.then(response => response.arrayBuffer())
.then(buffer => {
// Handle binary data
const bytes = new Uint8Array(buffer);
console.log('Binary data length:', bytes.length);
});
Personalizando las peticiones Node Fetch con encabezados y opciones
Estableciendo encabezados personalizados
fetch('<https://api.example.com/protected-data>', {
headers: {
'Authorization': 'Bearer YOUR_TOKEN_HERE',
'Content-Type': 'application/json',
'Accept': 'application/json',
'User-Agent': 'My Node.js Application'
}
})
.then(response => response.json())
.then(data => console.log(data));
Configurando opciones de petición
fetch('<https://api.example.com/data>', {
method: 'GET',
headers: { 'Content-Type': 'application/json' },
cache: 'no-cache',
redirect: 'follow', // follow, error, or manual
referrerPolicy: 'no-referrer'
})
.then(response => response.json())
.then(data => console.log(data));
Manejo de errores con Node Fetch
Manejo de errores integral
Un aspecto importante a entender sobre Node fetch es que no rechaza los códigos de estado de error HTTP. La promesa solo se rechaza en errores de red o si algo impidió que la petición se completara.
Aquí hay un enfoque integral para el manejo de errores:
async function fetchWithErrorHandling(url) {
try {
const response = await fetch(url);
// Check for HTTP errors
if (!response.ok) {
// Attempt to get error details from response
let errorDetails;
try {
errorDetails = await response.json();
} catch (e) {
errorDetails = await response.text();
}
throw new Error(
`HTTP error! Status: ${response.status}, Details: ${
typeof errorDetails === 'object'
? JSON.stringify(errorDetails)
: errorDetails
}`
);
}
return await response.json();
} catch (error) {
// Network errors, parsing errors, and our custom HTTP errors
console.error('Fetch failed:', error.message);
throw error; // Re-throw to allow calling code to handle
}
}
Implementando un tiempo de espera de petición con Node Fetch
Node fetch no tiene soporte integrado para el tiempo de espera, pero puedes implementarlo usando AbortController
:
async function fetchWithTimeout(url, options = {}, timeoutMs = 5000) {
const controller = new AbortController();
const { signal } = controller;
// Set up timeout
const timeout = setTimeout(() => {
controller.abort();
}, timeoutMs);
try {
const response = await fetch(url, { ...options, signal });
clearTimeout(timeout); // Clear timeout if fetch completes
if (!response.ok) {
throw new Error(`HTTP error! Status: ${response.status}`);
}
return await response.json();
} catch (error) {
clearTimeout(timeout);
if (error.name === 'AbortError') {
throw new Error(`Request timed out after ${timeoutMs}ms`);
}
throw error;
}
}
// Example usage
fetchWithTimeout('<https://api.example.com/data>', {}, 3000)
.then(data => console.log(data))
.catch(error => console.error('Error:', error.message));
Manejando la autenticación con Node Fetch
Autenticación básica
const username = 'user';
const password = 'password';
const credentials = Buffer.from(`${username}:${password}`).toString('base64');
fetch('<https://api.example.com/protected>', {
headers: {
'Authorization': `Basic ${credentials}`
}
})
.then(response => response.json())
.then(data => console.log(data));
Autenticación con token Bearer
const token = 'your_jwt_or_oauth_token';
fetch('<https://api.example.com/protected>', {
headers: {
'Authorization': `Bearer ${token}`
}
})
.then(response => response.json())
.then(data => console.log(data));
Mejores prácticas para usar Node Fetch en producción
- Siempre verifica el estado de la respuesta: No asumas que las respuestas son exitosas
- Maneja los diferentes tipos de contenido apropiadamente: Usa el método correcto para tu tipo de respuesta (json(), text(), etc.)
- Implementa un manejo de errores adecuado: Crea funciones de utilidad que manejen los errores de manera consistente
- Establece tiempos de espera de petición: Evita las peticiones colgadas con AbortController
- Crea wrappers de fetch reutilizables: Construye una capa de servicio con patrones de petición comunes
- Considera la lógica de reintento para las peticiones fallidas: Implementa un retroceso exponencial para las APIs inestables
- Usa variables de entorno para las URLs base: Mantén las URLs específicas del entorno fuera del código
Solución de problemas comunes de Node Fetch
Error "Fetch is not defined"
Si encuentras ReferenceError: fetch is not defined
, verifica:
- Estás usando Node.js v18+
- Para Node.js v18-v20, usa el flag
-experimental-fetch
- Para versiones antiguas, instala el paquete
node-fetch
Problemas con el certificado HTTPS
Node fetch hereda el manejo de certificados HTTPS de Node. Para certificados personalizados:
const https = require('https');
const fs = require('fs');
const httpsAgent = new https.Agent({
ca: fs.readFileSync('./custom-certificate.pem')
});
fetch('<https://api.example.com/data>', {
agent: httpsAgent
})
.then(response => response.json())
.then(data => console.log(data));
Conclusión: Adoptando Node Fetch en tus proyectos
La API Node fetch representa una mejora significativa en la forma en que realizamos peticiones HTTP en aplicaciones Node.js. Con su interfaz basada en promesas, su comportamiento consistente en todas las plataformas y su implementación nativa, se está convirtiendo en la opción preferida para el desarrollo moderno de Node.js.
Al dominar Node fetch, puedes crear un código más mantenible que aproveche las características modernas de JavaScript mientras disfrutas de un rendimiento mejorado en comparación con las bibliotecas de cliente HTTP más antiguas. A medida que la implementación estable continúa madurando en Node.js, podemos esperar que aún más desarrolladores adopten esta potente API como su enfoque estándar para realizar peticiones HTTP.
Ahora que tienes una comprensión completa de Node fetch, estás listo para implementarlo en tus propios proyectos y aprovechar esta potente API para todas tus necesidades de petición HTTP.