Saltar al contenido
Curso de Node.js y APIs
Todos los cursos

Ejercicio: Consumir APIs con fetch y variables de entorno

  • ⏱ 60 minutos
  • 📶 Nivel: intermedio

Objetivo

Consultar una API real desde un script de Node, guardar la configuración en un .env y escribir en JavaScript puro las utilidades que sostienen ese trabajo.

Cómo se trabaja

La parte A es práctica real en tu terminal (necesita internet). La parte B son cuatro funciones de JavaScript puro: un lector de .env, un constructor de URLs, un obtenerJson al que se le pasa fetch como argumento (así se puede probar sin red) y un lector de configuración. Pega solo el JavaScript, sin <script>.

▶ Prueba tu código aquí (opcional)
Consola

Pasos

Marca cada paso a medida que lo completes. Tu avance se guarda en este navegador.

💡 Pista 1: ¿tu .env no se carga?

Comprueba que ejecutas el comando desde la carpeta que contiene .env y que usas Node 20.6 o superior (node -v).

💡 Pista 2: parsearEnv

l.indexOf("=") te da la posición del primer igual. Clave: l.slice(0, i). Valor: l.slice(i + 1).

💡 Pista 3: obtenerJson

Es una función async. Recibe fetchFn en lugar de usar fetch directamente para que se pueda sustituir en las pruebas.

🔎 Comprueba tu trabajo

Pega tu código y pulsa Comprobar. La revisión ocurre en tu navegador; nada se envía a ningún sitio. Cada punto en rojo incluye una pista. Pega solo el JavaScript, sin las etiquetas <script>.

    ✅ Ver una solución posible

    Intenta resolverlo antes de mirar. Tu versión puede ser distinta y también correcta.

    utilidades.js
    function parsearEnv(texto) {
      const resultado = {};
      for (const linea of texto.split("\n")) {
        const l = linea.trim();
        if (l === "" || l.startsWith("#")) continue;
        const i = l.indexOf("=");
        if (i === -1) continue;
        const clave = l.slice(0, i).trim();
        let valor = l.slice(i + 1).trim();
        if (valor.length >= 2 && valor.startsWith('"') && valor.endsWith('"')) {
          valor = valor.slice(1, -1);
        }
        resultado[clave] = valor;
      }
      return resultado;
    }
    
    function construirUrl(base, params) {
      const limpio = {};
      for (const [k, v] of Object.entries(params)) {
        if (v !== undefined && v !== null) limpio[k] = v;
      }
      const query = new URLSearchParams(limpio).toString();
      return query ? base + "?" + query : base;
    }
    
    async function obtenerJson(fetchFn, url) {
      const respuesta = await fetchFn(url);
      if (!respuesta.ok) {
        throw new Error("HTTP " + respuesta.status);
      }
      return respuesta.json();
    }
    
    function leerConfig(env) {
      return {
        puerto: Number(env.PORT) || 3000,
        modo: env.NODE_ENV ?? "development",
      };
    }

    💡 🏁 Reto extra (opcional)

    Amplía obtenerJson para que reintente hasta 3 veces si el estado es 500 o superior (pero no si es 4xx), esperando un poco entre intentos.