APIs para Juniors: Tu Primera Guía Completa para Consumir Datos
¡Hola desarrolladores junior! ![]()
Las APIs son el corazón de las aplicaciones modernas, pero pueden parecer intimidantes al principio. Esta guía te enseñará todo lo que necesitas saber para trabajar con APIs de forma efectiva y profesional.
¿Qué es una API Realmente?
Imagina que una API es como un mesero en un restaurante:
-
Tú (frontend) haces un pedido (request)
-
El mesero (API) lleva tu pedido a la cocina (servidor)
-
La cocina prepara tu comida (procesa datos)
-
El mesero te trae tu plato (response)
// Ejemplo simple: "Pedirle" datos de usuarios a una API
fetch('https://api.ejemplo.com/usuarios')
.then(response => response.json()) // "Recibir el plato"
.then(usuarios => {
console.log('¡Mis usuarios!', usuarios);
});
Fetch: Tu Herramienta Principal
GET: Obtener Datos
// ✅ Forma básica de obtener datos
async function obtenerUsuarios() {
try {
const response = await fetch('https://jsonplaceholder.typicode.com/users');
// Verificar si la respuesta es exitosa
if (!response.ok) {
throw new Error(`Error: ${response.status}`);
}
const usuarios = await response.json();
console.log('Usuarios obtenidos:', usuarios);
return usuarios;
} catch (error) {
console.error('Algo salió mal:', error);
}
}
// Usar la función
obtenerUsuarios();
POST: Enviar Datos Nuevos
// ✅ Crear un nuevo usuario
async function crearUsuario(datosUsuario) {
try {
const response = await fetch('https://jsonplaceholder.typicode.com/users', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(datosUsuario)
});
if (!response.ok) {
throw new Error(`Error al crear usuario: ${response.status}`);
}
const nuevoUsuario = await response.json();
console.log('Usuario creado:', nuevoUsuario);
return nuevoUsuario;
} catch (error) {
console.error('Error:', error);
}
}
// Ejemplo de uso
const datosNuevoUsuario = {
name: 'Ana García',
email: 'ana@ejemplo.com',
phone: '123-456-7890'
};
crearUsuario(datosNuevoUsuario);
PUT: Actualizar Datos Completos
// ✅ Actualizar un usuario completo
async function actualizarUsuario(id, datosCompletos) {
try {
const response = await fetch(`https://jsonplaceholder.typicode.com/users/${id}`, {
method: 'PUT',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(datosCompletos)
});
const usuarioActualizado = await response.json();
console.log('Usuario actualizado:', usuarioActualizado);
return usuarioActualizado;
} catch (error) {
console.error('Error al actualizar:', error);
}
}
DELETE: Eliminar Datos
// ✅ Eliminar un usuario
async function eliminarUsuario(id) {
try {
const response = await fetch(`https://jsonplaceholder.typicode.com/users/${id}`, {
method: 'DELETE'
});
if (response.ok) {
console.log(`Usuario ${id} eliminado exitosamente`);
return true;
} else {
throw new Error('No se pudo eliminar el usuario');
}
} catch (error) {
console.error('Error:', error);
return false;
}
}
Manejo de Estados en la UI
Indicadores de Carga
// ✅ Mostrar loading mientras cargan los datos
async function cargarYMostrarUsuarios() {
// Mostrar indicador de carga
document.getElementById('loading').style.display = 'block';
document.getElementById('error').style.display = 'none';
try {
const usuarios = await obtenerUsuarios();
mostrarUsuarios(usuarios);
} catch (error) {
mostrarError('No se pudieron cargar los usuarios');
} finally {
// Ocultar indicador de carga
document.getElementById('loading').style.display = 'none';
}
}
function mostrarUsuarios(usuarios) {
const contenedor = document.getElementById('usuarios-lista');
contenedor.innerHTML = ''; // Limpiar contenido anterior
usuarios.forEach(usuario => {
const div = document.createElement('div');
div.className = 'usuario-card';
div.innerHTML = `
<h3>${usuario.name}</h3>
<p>Email: ${usuario.email}</p>
<p>Teléfono: ${usuario.phone}</p>
`;
contenedor.appendChild(div);
});
}
function mostrarError(mensaje) {
const errorDiv = document.getElementById('error');
errorDiv.textContent = mensaje;
errorDiv.style.display = 'block';
}
HTML Básico para el Ejemplo
<!-- ✅ Estructura básica para mostrar datos -->
<!DOCTYPE html>
<html>
<head>
<title>Mi App con API</title>
<style>
.loading { text-align: center; color: #666; }
.error { color: red; background: #fee; padding: 10px; border-radius: 4px; }
.usuario-card {
border: 1px solid #ddd;
padding: 15px;
margin: 10px 0;
border-radius: 8px;
}
</style>
</head>
<body>
<h1>Lista de Usuarios</h1>
<button onclick="cargarYMostrarUsuarios()">Cargar Usuarios</button>
<div id="loading" class="loading" style="display: none;">
Cargando usuarios...
</div>
<div id="error" class="error" style="display: none;"></div>
<div id="usuarios-lista"></div>
<script src="mi-script.js"></script>
</body>
</html>
Códigos de Estado HTTP (Status Codes)
Entender estos códigos te ayudará a manejar mejor las respuestas:
// ✅ Manejar diferentes códigos de estado
async function manejarRespuesta(response) {
switch (response.status) {
case 200:
console.log('✅ Todo perfecto');
return await response.json();
case 201:
console.log('✅ Recurso creado exitosamente');
return await response.json();
case 404:
throw new Error('❌ No encontrado - verifica la URL');
case 500:
throw new Error('❌ Error del servidor - intenta más tarde');
case 401:
throw new Error('❌ No autorizado - verifica tu token');
default:
throw new Error(`❌ Error desconocido: ${response.status}`);
}
}
Códigos más comunes:
-
200:
OK - Todo salió bien -
201:
Created - Recurso creado -
400:
Bad Request - Error en tu solicitud -
401:
Unauthorized - Necesitas autenticación -
404:
Not Found - El recurso no existe -
500:
Server Error - Error del servidor
Mejores Prácticas para Juniors
1. Siempre Manejar Errores
// ❌ Malo: sin manejo de errores
fetch('/api/datos').then(response => response.json()).then(data => console.log(data));
// ✅ Bueno: con manejo completo
async function obtenerDatos() {
try {
const response = await fetch('/api/datos');
if (!response.ok) {
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
}
const data = await response.json();
return data;
} catch (error) {
console.error('Error al obtener datos:', error);
// Mostrar mensaje al usuario
mostrarMensajeError('No se pudieron cargar los datos');
throw error; // Re-lanzar para que el código que llama pueda manejarlo
}
}
2. Validar Datos Antes de Enviar
// ✅ Validar antes de enviar a la API
function validarDatosUsuario(datos) {
const errores = [];
if (!datos.name || datos.name.trim().length < 2) {
errores.push('El nombre debe tener al menos 2 caracteres');
}
if (!datos.email || !datos.email.includes('@')) {
errores.push('El email debe ser válido');
}
if (!datos.phone || datos.phone.length < 10) {
errores.push('El teléfono debe tener al menos 10 dígitos');
}
return {
esValido: errores.length === 0,
errores: errores
};
}
async function crearUsuarioConValidacion(datos) {
const validacion = validarDatosUsuario(datos);
if (!validacion.esValido) {
console.error('Datos inválidos:', validacion.errores);
mostrarErrores(validacion.errores);
return null;
}
return await crearUsuario(datos);
}
3. Usar Timeouts para Evitar Esperas Infinitas
// ✅ Función con timeout
function fetchConTimeout(url, options = {}, timeout = 5000) {
return Promise.race([
fetch(url, options),
new Promise((_, reject) =>
setTimeout(() => reject(new Error('Timeout')), timeout)
)
]);
}
// Uso
try {
const response = await fetchConTimeout('/api/datos-lentos', {}, 3000);
const data = await response.json();
} catch (error) {
if (error.message === 'Timeout') {
console.error('La solicitud tardó demasiado');
} else {
console.error('Otro error:', error);
}
}
Ejemplo Práctico: Lista de Tareas con API
// ✅ Aplicación completa de tareas con API
class GestorTareas {
constructor() {
this.baseUrl = 'https://jsonplaceholder.typicode.com/todos';
this.contenedor = document.getElementById('tareas-lista');
}
async cargarTareas() {
try {
this.mostrarCargando(true);
const response = await fetch(this.baseUrl);
if (!response.ok) throw new Error('Error al cargar tareas');
const tareas = await response.json();
// Mostrar solo las primeras 10 para el ejemplo
this.renderizarTareas(tareas.slice(0, 10));
} catch (error) {
this.mostrarError('No se pudieron cargar las tareas');
} finally {
this.mostrarCargando(false);
}
}
async agregarTarea(titulo) {
try {
const nuevaTarea = {
title: titulo,
completed: false,
userId: 1
};
const response = await fetch(this.baseUrl, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(nuevaTarea)
});
if (!response.ok) throw new Error('Error al crear tarea');
const tareaCreada = await response.json();
this.agregarTareaALista(tareaCreada);
} catch (error) {
this.mostrarError('No se pudo crear la tarea');
}
}
renderizarTareas(tareas) {
this.contenedor.innerHTML = '';
tareas.forEach(tarea => {
const div = document.createElement('div');
div.className = `tarea ${tarea.completed ? 'completada' : ''}`;
div.innerHTML = `
<span>${tarea.title}</span>
<button onclick="gestor.toggleTarea(${tarea.id})">
${tarea.completed ? 'Pendiente' : 'Completar'}
</button>
`;
this.contenedor.appendChild(div);
});
}
mostrarCargando(mostrar) {
document.getElementById('loading').style.display = mostrar ? 'block' : 'none';
}
mostrarError(mensaje) {
console.error(mensaje);
// Aquí puedes mostrar el error en la UI
}
}
// Inicializar
const gestor = new GestorTareas();
gestor.cargarTareas();
APIs Gratuitas para Practicar
Estas APIs no requieren autenticación y son perfectas para aprender:
-
JSONPlaceholder:
https://jsonplaceholder.typicode.com/-
Posts, comentarios, usuarios, fotos
-
Perfecto para CRUD básico
-
-
OpenWeatherMap:
https://openweathermap.org/api- Datos del clima (requiere API key gratuita)
-
Cat Facts:
https://catfact.ninja/fact- Datos simples para comenzar
-
Dog API:
https://dog.ceo/api/breeds/image/random- Imágenes aleatorias de perros
Tips para Debuggear APIs
// ✅ Función helper para debuggear
async function debugFetch(url, options = {}) {
console.log('📡 Haciendo request a:', url);
console.log('📝 Opciones:', options);
try {
const response = await fetch(url, options);
console.log('📨 Status:', response.status);
console.log('📋 Headers:', [...response.headers.entries()]);
if (!response.ok) {
console.error('❌ Request falló:', response.status, response.statusText);
}
return response;
} catch (error) {
console.error('❌ Error de red:', error);
throw error;
}
}
Ejercicio Práctico
Desafío: Crea una pequeña aplicación que:
-
Muestre una lista de usuarios desde JSONPlaceholder
-
Permita crear un nuevo usuario (simulado)
-
Tenga indicadores de carga
-
Maneje errores apropiadamente
Bonus: Agrega filtros de búsqueda y paginación básica.
Resumen de Conceptos Clave
-
API: Interfaz que permite comunicación entre aplicaciones
-
Fetch: Función de JavaScript para hacer requests HTTP
-
async/await: Forma moderna de manejar código asíncrono
-
Status codes: Códigos que indican el resultado de un request
-
JSON: Formato estándar para intercambio de datos
-
CRUD: Create, Read, Update, Delete - operaciones básicas
¡Lo Lograste!
Trabajar con APIs puede parecer complicado al principio, pero con práctica se vuelve natural. Recuerda:
-
Siempre maneja errores
-
Muestra feedback al usuario (loading, errores)
-
Valida datos antes de enviarlos
-
Usa herramientas de desarrollo para debuggear
¿Qué API vas a probar primero? ¿Tienes alguna duda específica sobre requests HTTP? ¡Comparte tu experiencia en los comentarios!
Próxima semana: “CSS Flexbox para Juniors: Layouts que Realmente Funcionan”
#JuniorDev #APIs javascript webdev #LearningToCode #Fetch #HTTP
