Conectar una API de NestJS a PostgreSQL se vuelve mucho más simple cuando usas un ORM. En esta guía aprenderás cómo configurar TypeORM con NestJS y PostgreSQL, paso a paso, y cómo proteger tus credenciales con variables de entorno usando ConfigService. Es una pieza clave si estás construyendo una API con persistencia real y quieres seguir buenas prácticas desde el inicio.
Qué es un ORM y por qué usarlo en NestJS
Un ORM (Object Relational Mapper) te permite conectarte a tu base de datos siguiendo un patrón orientado a objetos. En vez de escribir SQL crudo, declaras entidades como clases y el framework se encarga de mapear tablas a objetos que puedes consultar desde tu código [00:08].
¿Qué es un ORM? Es una capa que traduce tablas de una base de datos relacional a objetos en tu lenguaje de programación. Así puedes leer, escribir y relacionar datos sin escribir SQL directamente.
Este patrón no es exclusivo de Node. Frameworks como Laravel en PHP o Django en Python tienen sus propios ORMs. En el ecosistema de NestJS, TypeORM es la opción más usada por su integración nativa, aunque también puedes elegir Prisma, MikroORM o Sequelize según tu proyecto [00:31].
Qué bases de datos soporta TypeORM
TypeORM es flexible y se conecta a múltiples motores. Entre los más comunes están:
- MySQL y MariaDB.
- PostgreSQL.
- SQLite.
- Microsoft SQL Server y Oracle.
- MongoDB, si necesitas trabajar con NoSQL.
Esto te da libertad para cambiar de motor sin reescribir toda tu lógica de acceso a datos [01:05].
Cómo instalar TypeORM y el driver de PostgreSQL en NestJS
Para empezar necesitas dos dependencias: el módulo de NestJS para TypeORM y el driver nativo de PostgreSQL para Node, que se llama pg [02:15].
En la terminal, dentro de tu proyecto, ejecuta:
bash
npm install --save @nestjs/typeorm typeorm pg
La documentación oficial de NestJS suele mostrar el ejemplo con MySQL, pero como vamos a usar Postgres, el driver correcto es pg. Si llegas a equivocarte de driver, el ORM te lanzará un error indicando que el paquete de conexión no está instalado [05:50].
Cómo configurar TypeOrmModule en el AppModule
La primera versión de la conexión vive en AppModule. Importas TypeOrmModule y usas forRoot con un objeto de configuración que indica el tipo de base, host, puerto, usuario, contraseña y nombre de la base [03:08].
Una configuración inicial se ve así:
typescript
TypeOrmModule.forRoot({
type: 'postgres',
host: 'localhost',
port: 5432,
username: 'bloguser',
password: 'tu_password',
database: 'myblogdb',
autoLoadEntities: true,
synchronize: true,
})
Dos propiedades importantes acá: autoLoadEntities en true carga automáticamente las entidades que registres en tus módulos, y synchronize en true sincroniza el esquema con tus entidades. Esto último es útil en desarrollo, pero nunca lo dejes activo en producción porque puede modificar tus tablas sin aviso.
Si tu API corre fuera de Docker y la base sí está en un contenedor, el host correcto desde tu máquina sigue siendo localhost apuntando al puerto expuesto, normalmente el 5432 de PostgreSQL [04:12].
Cómo verificar que la conexión funciona
Al correr la aplicación, TypeORM imprime en consola un mensaje confirmando que las dependencias se inicializaron correctamente. Si las credenciales están mal, verás un error claro indicando que no pudo establecer conexión con la base [05:30].
¿Para qué sirve synchronize: true en TypeORM? Sincroniza automáticamente tu esquema de base de datos con las entidades de tu código. Úsalo solo en desarrollo, nunca en producción.
Por qué mover las credenciales a variables de entorno
Dejar el password directamente en el código de TypeScript tiene dos problemas serios. El primero es de seguridad: ese código suele subirse a un repositorio remoto y puede ser visto por otros desarrolladores. El segundo es de flexibilidad: cada vez que despliegues a otro entorno (staging, producción) tendrías que tocar el código en lugar de cambiar una configuración [07:10].
La solución es usar un archivo .env, que está ignorado por git, junto con un módulo de configuración tipado.
Qué variables definir en el archivo .env
Para una conexión a PostgreSQL necesitas cinco variables claras y reutilizables:
POSTGRES_HOST con valor localhost.
POSTGRES_PORT con valor 5432.
POSTGRES_DB con el nombre de la base, por ejemplo myblogdb.
POSTGRES_USER con el usuario, como bloguser.
POSTGRES_PASSWORD con la contraseña.
Una buena práctica es mantener un archivo .env.example sin valores reales, solo con los nombres de las variables, para que cualquier persona que clone el repo sepa qué configurar [07:55].
Después mapeas esas variables en tu interfaz tipada de entorno. Todas son string, excepto el puerto que es number.
Cómo usar forRootAsync con ConfigService en TypeORM
Desde AppModule no puedes inyectar dependencias por constructor porque no es una clase de servicio. Para resolverlo, cambias forRoot por forRootAsync, que acepta una función useFactory capaz de recibir dependencias [08:40].
La configuración queda así:
typescript
TypeOrmModule.forRootAsync({
inject: [ConfigService],
useFactory: (configService: ConfigService<EnvVars>) => ({
type: 'postgres',
host: configService.get('POSTGRES_HOST', { infer: true }),
port: configService.get('POSTGRES_PORT', { infer: true }),
username: configService.get('POSTGRES_USER', { infer: true }),
password: configService.get('POSTGRES_PASSWORD', { infer: true }),
database: configService.get('POSTGRES_DB', { infer: true }),
autoLoadEntities: true,
synchronize: true,
}),
})
Usar la opción { infer: true } activa la inferencia de tipos. Si te equivocas escribiendo el nombre de una variable, TypeScript te avisa de inmediato en lugar de fallar silenciosamente en runtime [09:50].
¿Cuándo usar forRootAsync en NestJS? Cuando tu configuración depende de otros servicios, como ConfigService. Te permite inyectar dependencias y construir la configuración de forma dinámica.
Un detalle fácil de pasar por alto: la propiedad para inyectar dependencias se llama inject, no imports. Confundir ese nombre genera un error al levantar la app [10:45].
Con esta configuración, tu código ya no tiene credenciales quemadas. En local lees del .env, y en producción inyectas las variables reales desde el servidor o el orquestador. Esa es la forma correcta de conectar NestJS a PostgreSQL con TypeORM y mantener tu API segura y portable.
¿Ya tienes tu conexión funcionando? Cuéntame en los comentarios qué motor de base de datos estás usando y si prefieres TypeORM o Prisma para tu próximo proyecto.