Saltar al contenido

Lección 2 de 12 · Lectura y práctica

Estructura de proyecto, env vars y configuracion

Estructura de proyecto, variables de entorno y configuración Una API que funciona en tu máquina pero falla en producción casi siempre tiene un problema de configuración. La regla de oro del enfoque Twelve-Factor es separar la.

Del concepto a la práctica

Taller de esta lección

Separar app de server permite probar rutas sin abrir un puerto y hace visible qué configuración es obligatoria. La validación debe ocurrir al arrancar, no después de recibir la primera solicitud.

Ejemplo resuelto

js
const required = (name) => {
  const value = process.env[name];
  if (!value) throw new Error(`Falta ${name}`);
  return value;
};
const portText = process.env.PORT ?? "3000";
const port = Number(portText);
if (!/^\d+$/.test(portText) || !Number.isInteger(port) || port < 1 || port > 65535) {
  throw new Error("PORT inválido");
}
export const config = {
  port,
  databaseUrl: required('DATABASE_URL')
};

Con PORT=4100 y una URL presente, el puerto resulta 4100; sin DATABASE_URL, el proceso falla con un mensaje identificable.

Usa package.json con type:module para este export, o convierte coherentemente a CommonJS. Tener .env.example no carga el entorno: usa el mecanismo de carga declarado por tu runtime. Prueba PORT=abc, PORT=0 y PORT=65536: todos deben fallar antes de escuchar. Nunca incluyas la URL con contraseña en logs; un valor requerido presente tampoco demuestra que la base responda.

Pruébalo

  1. Crea src/config.js y src/server.js separados.

  2. Define PORT y DATABASE_URL solo en el entorno local.

  3. Ejecuta una vez con ambas variables y otra sin la segunda.

Error frecuente: usar Number(process.env.PORT) sin comprobar NaN. Corrige aceptando un valor predeterminado o rechazando explícitamente un puerto no numérico.

Ejercicio: documenta PORT y DATABASE_URL en .env.example, sin valores secretos.

Comprueba tu resultado

otra persona puede identificar ambas variables y el arranque incompleto falla antes de escuchar.

Navegador, API y base de datos conectados por solicitudes, consultas y respuestas en sentidos opuestos.
CursaloMapa de práctica
Del navegador a los datos

El navegador envía una solicitud a la API. El servidor valida la operación y consulta los datos; después devuelve una respuesta que el navegador puede mostrar. La base de datos se comunica con el servidor y no directamente con el navegador.

Ver la infografía en tamaño completo ↗

Estructura de proyecto, variables de entorno y configuración

Una API que funciona en tu máquina pero falla en producción casi siempre tiene un problema de configuración. La regla de oro del enfoque Twelve-Factor es separar la configuración del código: lo que cambia entre tu portátil, el servidor de pruebas y producción (puertos, URLs de base de datos, claves) vive en el entorno, nunca dentro de los archivos versionados en Git.

Una estructura sencilla y escalable

mi-api/
  src/
    config.js        # lee y valida process.env
    app.js           # crea la app Express (sin escuchar)
    server.js        # arranca y escucha en el puerto
    routes/
    middleware/
    db/
  .env               # NUNCA se sube a Git
  .env.example       # plantilla que sí se versiona
  .gitignore

Separar app.js (la configuración de Express) de server.js (el listen) te permite importar la app en tus tests sin abrir un puerto real.

Centraliza y valida la configuración

// src/config.js
import 'dotenv/config';

function required(name) {
  const value = process.env[name];
  if (!value) throw new Error(`Falta la variable de entorno ${name}`);
  return value;
}

export const config = {
  port: Number(process.env.PORT ?? 3000),
  databaseUrl: required('DATABASE_URL'),
  nodeEnv: process.env.NODE_ENV ?? 'development',
};

Atención

Añade .env a tu .gitignore el primer día. Subir credenciales a un repositorio, aunque sea privado, es la fuga de secretos más común y la más cara de revertir.

Falla rápido, no a medias

Si falta DATABASE_URL, es mejor que la app no arranque a que lance un error críptico en la primera consulta de un usuario real. Validar al inicio convierte un fallo silencioso en un error claro y temprano.

¿Qué archivo debe versionarse en Git para documentar las variables sin filtrar secretos?

.env.example documenta qué variables existen sin exponer valores reales. El .env de verdad queda fuera de Git, y nunca se hardcodean secretos en el código.

Ejercicio práctico

Objetivo: montar una configuración robusta que falle rápido.

  1. Crea config.js con la función required() de arriba y al menos PORT y DATABASE_URL.
  2. Crea un .env.example y añade .env al .gitignore.
  3. Añade scripts a package.json: "dev": "node --watch src/server.js" y "start": "node src/server.js".
  4. Arranca sin DATABASE_URL y comprueba que el proceso muere con un mensaje claro.

Entregable: tu config.js, tu .env.example y una captura del error al faltar una variable.

Para recordar

  • La configuración va en el entorno, no en el código.
  • .env nunca se sube; .env.example sí.
  • Valida todas las variables al arrancar y falla rápido con un mensaje útil.

Sigue con Node.js y APIs con Express

Esta lección forma parte de un curso de Cursalo. Revisa su programa y elige entre la compra individual o el acceso a toda la escuela.

Si ya tenías acceso a este curso, entra con tu cuenta: tus derechos y tu progreso se conservan. No necesitas comprarlo de nuevo.

01 / ELEGIR UNA RUTA

El próximo paso

Aprende IA mientras construyes algo que sí necesitas.

Empieza por el curso inicial o explora el catálogo para encontrar una práctica alineada con tu trabajo.