TypeORM es un ORM (Object Relational Mapper) potente y flexible para TypeScript y JavaScript que simplifica enormemente la interacción con bases de datos. Al combinar TypeORM con NestJS, puedes desarrollar aplicaciones eficientes, con una arquitectura limpia y que aprovechan al máximo el poder de TypeScript.
A continuación, se detallará cómo configurar TypeORM con una base de datos MySQL en un proyecto NestJS, aplicando las mejores prácticas para una configuración segura y modular.
Instalación de dependencias
Esto incluye el paquete específico de NestJS para TypeORM, el paquete principal de TypeORM y el controlador de MySQL. Además, para una gestión segura de las credenciales, instalaremos el paquete de configuración de NestJS:
npm install --save @nestjs/typeorm typeorm mysql2 @nestjs/config
# o
yarn add @nestjs/typeorm typeorm mysql2 @nestjs/config
Configuración de Variables de Entorno
¡Recomendación! Nunca incrustes credenciales sensibles de base de datos directamente en tu código. Utiliza variables de entorno para gestionar esta información de forma segura y adaptable a diferentes entornos (desarrollo, producción, etc.).
Crearemos un archivo .env
en la raíz de tu proyecto (y lo añadiremos a .gitignore
para no subirlo al control de versiones) con tus credenciales:
.env
DB_TYPE=mysql
DB_HOST=localhost
DB_PORT=3306
DB_USERNAME=root
DB_PASSWORD=tu_contraseña_segura
DB_DATABASE=nombre_de_tu_base_de_datos
Configuración en el Módulo Raíz (AppModule
) con TypeOrmModule.forRoot()
Luego, en tu módulo principal (AppModule
), importarás TypeOrmModule
y ConfigModule
de @nestjs/config
. Utilizaremos TypeOrmModule.forRoot()
para establecer la conexión global a la base de datos y leer las credenciales desde las variables de entorno:
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { ConfigModule, ConfigService } from '@nestjs/config'; // Importar ConfigModule y ConfigService
@Module({
imports: [
// 1. Configurar el módulo de configuración para cargar las variables de entorno
ConfigModule.forRoot({
isGlobal: true, // Hace que ConfigModule esté disponible globalmente
envFilePath: '.env', // Ruta a tu archivo .env
}),
// 2. Configurar TypeORM para la conexión a la base de datos
TypeOrmModule.forRootAsync({
imports: [ConfigModule], // Importar ConfigModule para poder usar ConfigService
useFactory: (configService: ConfigService) => ({
type: configService.get<"mysql">('DB_TYPE'), // 'mysql' como tipo de DB
host: configService.get<string>('DB_HOST'),
port: configService.get<number>('DB_PORT'),
username: configService.get<string>('DB_USERNAME'),
password: configService.get<string>('DB_PASSWORD'),
database: configService.get<string>('DB_DATABASE'),
// Esto buscará las entidades automáticamente. Ver siguiente sección para un enfoque modular.
entities: [__dirname + '/**/*.entity{.ts,.js}'],
synchronize: true, // ¡ATENCIÓN! Usar solo en desarrollo, nunca en producción.
// En producción, usa migraciones (ver lecciones futuras).
}),
inject: [ConfigService], // Inyectar ConfigService en la factoría
}),
],
// controllers: [],
// providers: [],
})
export class AppModule {}
Explicación de las propiedades clave en forRootAsync
:
Guarda tu progreso
Inicia sesión para no perder tu progreso y accede a miles de tutoriales, ejercicios prácticos y nuestro asistente de IA.
Más de 25.000 desarrolladores ya confían en CertiDevs
imports: [ConfigModule]
: Necesario para queConfigService
esté disponible dentro deuseFactory
.useFactory: (configService: ConfigService) => ({ ... })
: Permite definir la configuración de forma asíncrona, lo que es ideal para cargar valores deConfigService
.type
: El tipo de base de datos a la que te vas a conectar (ej.,'mysql'
,'postgres'
,'sqlite'
).host
: La dirección del servidor de la base de datos.port
: El puerto por el cual se accede a la base de datos.username
ypassword
: Las credenciales para acceder a la base de datos.database
: El nombre de la base de datos a la que te quieres conectar.entities
: Especifica la ubicación de tus entidades (modelos de base de datos).__dirname + '/**/*.entity{.ts,.js}'
es un enfoque global que escanea todas las subcarpetas. Para un enfoque más modular, veremosforFeature()
a continuación.synchronize: true
: Si estrue
, TypeORM generará o actualizará automáticamente las tablas en la base de datos de acuerdo a tus entidades. ¡Es CRÍTICO no usarsynchronize: true
en entornos de producción, ya que puede llevar a la pérdida de datos o problemas de migración! En producción, se recomienda encarecidamente utilizar las funcionalidades de migraciones de TypeORM.
Registro de Entidades en Módulos de Características (TypeOrmModule.forFeature()
)
En NestJS, es una buena práctica organizar tu aplicación en módulos de características (ej., UsersModule
, ProductsModule
). Cada uno de estos módulos debería gestionar sus propias entidades. Para esto, TypeORM proporciona TypeOrmModule.forFeature()
.
TypeOrmModule.forFeature()
registra las entidades específicas de un módulo, lo que permite que los repositorios de esas entidades sean inyectados en los servicios dentro de ese módulo.
Ejemplo en un UsersModule
(Módulo de Usuarios):
Asume que tienes una entidad User
(user.entity.ts
):
// users/user.entity.ts
import { Entity, PrimaryGeneratedColumn, Column } from 'typeorm';
@Entity()
export class User {
@PrimaryGeneratedColumn()
id: number;
@Column({ unique: true })
username: string;
@Column()
password?: string; // Opcional, pero en un caso real se gestionaría con hash
}
Ahora, registra esta entidad en tu UsersModule
:
// users/users.module.ts
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { UsersController } from './users.controller';
import { UsersService } from './users.service';
import { User } from './user.entity'; // Importa la entidad User
@Module({
imports: [
TypeOrmModule.forFeature([User]), // Registra la entidad User para este módulo
],
controllers: [UsersController],
providers: [UsersService],
exports: [TypeOrmModule] // Si quieres que repositorios de este módulo estén disponibles en otros módulos.
// O exporta los servicios que usan los repositorios: exports: [UsersService]
})
export class UsersModule {}
Con TypeOrmModule.forFeature([User])
, el UsersService
(o cualquier otro proveedor en UsersModule
) podrá inyectar UserRepository
para interactuar con la tabla User
.
Conclusión
Al seguir estos pasos, habrás completado una configuración robusta de TypeORM con MySQL en tu proyecto NestJS. El uso de variables de entorno garantiza seguridad y flexibilidad, mientras que la combinación de forRoot()
en el módulo raíz y forFeature()
en los módulos de características promueve una arquitectura modular, escalable y fácil de mantener. Estás listo para aprovechar todas las ventajas de TypeORM para gestionar tus datos de manera eficiente.
Aprendizajes de esta lección
- Comprender el propósito de TypeORM y ORM.
- Aprender a instalar las dependencias necesarias para configurar TypeORM con MySQL en NestJS.
- Dominar la configuración de TypeORM.
- Conocer las propiedades esenciales de la configuración de TypeORM.
Completa Nest y certifícate
Únete a nuestra plataforma y accede a miles de tutoriales, ejercicios prácticos, proyectos reales y nuestro asistente de IA personalizado para acelerar tu aprendizaje.
Asistente IA
Resuelve dudas al instante
Ejercicios
Practica con proyectos reales
Certificados
Valida tus conocimientos
Más de 25.000 desarrolladores ya se han certificado con CertiDevs