Contenido del curso

Fundamentos y Primer CRUD

Base de Datos y Persistencia con TypeORM

Variables de entorno seguras en NestJS

Resumen

Configurar variables de entorno en NestJS te permite separar credenciales, llaves de API y parámetros sensibles del código fuente, algo indispensable cuando tu aplicación corre en ambientes distintos como desarrollo y producción. Aquí aprendes a instalar @nestjs/config, inyectar el ConfigService y tipar tus variables para evitar errores silenciosos.

¿Por qué necesitas variables de entorno en una app NestJS?

Una aplicación profesional rara vez se ejecuta en un solo lugar. En producción manejas llaves reales de base de datos, tokens de servicios externos y configuraciones optimizadas. En desarrollo sueles tener accesos limitados, modo debug y credenciales de prueba.

Meter esos valores directamente en el código es un riesgo enorme. Si subes un token a GitHub, la propia plataforma te avisa por correo y te obliga a revocarlo, porque cualquiera con acceso al repositorio podría usarlo.

¿Qué es una variable de entorno? Es un valor externo al código que tu aplicación lee al arrancar. Sirve para guardar credenciales, llaves de API y parámetros que cambian entre ambientes sin tocar el código.

¿Cómo instalar y configurar @nestjs/config de forma global?

NestJS ofrece un paquete oficial llamado @nestjs/config que centraliza todo el manejo de configuración [3:50]. Lo instalas con npm y lo registras en tu AppModule.

La clave está en configurarlo como global, así cualquier controlador, servicio o módulo puede inyectar el ConfigService sin volver a importar nada.

ts imports: [ ConfigModule.forRoot({ isGlobal: true, }), ],

Si al guardar el archivo te aparecen errores de formato, corre npm run format en la terminal. Prettier alinea espacios, tags y deja todo el código consistente sin que tengas que ajustarlo a mano.

¿Para qué sirve el archivo .env y el .env.example?

El archivo .env vive en la raíz del proyecto y guarda los valores reales: tokens, llaves, URLs de base de datos. Este archivo nunca se sube al repositorio; por eso aparece listado dentro del .gitignore por defecto, junto con variantes como .env.local.

Al lado colocas un .env.example que sí se trackea. Contiene los nombres de las variables con valores vacíos y le sirve de guía a cualquier desarrollador nuevo que clone el proyecto.

  • El nuevo dev clona el repo y no encuentra .env.
  • Lee .env.example para saber qué variables existen.
  • Pide los valores reales al equipo y los pega en su propio .env local.

¿Cómo leer variables de entorno con ConfigService?

Dentro de cualquier controlador o servicio inyectas ConfigService en el constructor siguiendo el patrón de inyección de dependencias que ya usas con tus propios servicios [9:00].

ts constructor( private readonly appService: AppService, private readonly configService: ConfigService, ) {}

El readonly es opcional pero recomendable: evita que sobrescribas la dependencia por accidente. Para obtener un valor llamas al método get con el nombre exacto de la variable.

ts const myVar = this.configService.get<string>('MY_VAR');

Si el archivo .env no existe o la variable no está definida, get devuelve undefined. Por eso conviene tipar la respuesta y, mejor aún, validar que el valor existe antes de usarlo.

¿Qué pasa si olvido crear el archivo .env? El ConfigService.get() devuelve undefined. Tu aplicación no falla al arrancar, pero el valor llegará vacío al lugar donde lo uses, lo que suele provocar errores en runtime.

¿Cómo recargar variables después de editar el .env?

NestJS no detecta cambios en el .env aunque tengas el modo watch activo. Cada vez que agregues, edites o borres una variable, detén el servidor y vuelve a ejecutarlo con npm run start:dev. Sin ese reinicio el ConfigService sigue leyendo los valores anteriores.

¿Cómo tipar las variables de entorno con una interfaz?

Llamar variables por string suelto es frágil: un typo como openAPIKy en lugar de openAPIKey no lanza error, simplemente devuelve undefined. La solución es declarar una interfaz que describa todas tus variables [16:30].

Crea un archivo envs.model.ts y exporta una interfaz con cada variable y su tipo esperado.

ts export interface Env { MY_VAR: string; OPEN_API_KEY: string; }

Luego al inyectar el ConfigService le pasas ese tipo genérico y activas la bandera infer en cada llamada a get.

ts private readonly configService: ConfigService<Env>

const key = this.configService.get('OPEN_API_KEY', { infer: true });

Con esa configuración TypeScript te marca un error rojo si escribes mal el nombre de una variable. Atrapas typos en tiempo de compilación, no en producción cuando ya rompió algo.

¿Cómo cumplir con REST API al inyectar varios servicios?

Al resolver el reto anterior viste que un mismo controlador puede inyectar más de un servicio, por ejemplo AppService y UserService dentro de AppController. NestJS maneja esos servicios bajo el patrón singleton: existe una sola instancia compartida, no se crea una nueva por cada controlador que la solicite.

Eso significa que si UserController modifica el array de usuarios, AppController ve los mismos datos al consultarlo. Útil, pero cuidado con un detalle: si expones un endpoint llamado /mytest que devuelve usuarios, estás rompiendo la convención REST.

  • GET /users debería retornar la lista de usuarios.
  • POST /users debería crear un usuario.
  • DELETE /users/:id debería eliminar uno.

Un endpoint como mytest no comunica qué recurso maneja ni qué acción ejecuta. Reutilizar servicios está bien; nombrar mal los endpoints, no.

Ahora tienes el ConfigService disponible globalmente, tipado y seguro. Prueba moverlo desde el AppController al AppService y comprueba que la inyección funciona igual desde cualquier punto. ¿Qué variable agregarías primero a tu .env?