Uso de Módulos Globales en NestJS para Inyecciones Compartidas
Resumen
Al desarrollar una aplicación con NestJS, existen necesidades de importar módulos cruzados o de importar un mismo servicio en varios módulos. Lo anterior, hace que la cantidad de imports en cada módulo crezca y se vuelva complicado de escalar.
Cómo usar el módulo global
NestJS otorga la posibilidad de crear módulos globales que se importarán automáticamente en todos los otros módulos de la aplicación, sin necesidad de importarlos explícitamente.
Todos los servicios que importes en este módulo, estarán disponibles para su utilización en cualquier otro módulo.
Es importante no abusar de esta característica y no tener más de un módulo global para controlar las importaciones. Pueden ocurrir errores de dependencias circulares que suceden cuando el Módulo A importa al Módulo B y este a su vez importa al Módulo A. El decorador @Global() te ayudará a resolver estos problemas.
// src/app.module.ts...import{DatabaseModule}from'./database/database.module';@Module({imports:[HttpModule,UsersModule,ProductsModule,DatabaseModule// 👈 Use DatabaseModule like global Module],...})exportclassAppModule{}
// src/app.module.ts...import{DatabaseModule}from'./database/database.module';@Module({imports:[...DatabaseModule// 👈 Use DatabaseModule like global Module],...})exportclassAppModule{}
Listo, ahora podremos usar todos los controladores, modulos y providers que fueron declarados en el modulo global sin tener que instanciar el modulo DatabaseModule en los modulos que se requieran
Un AppModule se considera más como la raíz del app el módulo principal por eso no se considera global, solo puede haber un módulo principal, pero pueden existir varios módulos globales.
Global Modulo crea una instancia para todos los modulos, no es necesario exportar ni importar
El uso de forwardRef() para solucionar una dependencia circular seria mas adecuado que hacer global un modulo?
Hola, depende mucho del escenario, es decir creo que si un servicio se comparte con varios módulos tiene sentido que vaya en un GlobalModule, pero si es caso entre dos servicios el forwardRef es una buena solución.
Tuve un caso donde necesitaba la referencia circular, no se me había ocurrido usar el global pero lo solucioné con esto:
En el Module1, hago la importación del Module2
imports: [ forwardRef(() => Module2)
]
y en el Module2, importo el Module1.
imports: [ forwardRef(() => Module1)
]
Esto es una mala práctica?
Cuál es la ventaja de hacer un provider global, por ejemplo para un API KEY de esta manera en lugar de hacer solo llamarlo con un process.env.API_KEY en el lugar en el que lo necesitemos?
No logro entender el valor que hacer tantos pasos extra ofrece 😅
Hola, el beneficio no solo está en obtener una variable de ambiente está en que puedes validar la integridad de los variables de ambiente y además de tener tipado de estas.
Hola primero gracias por lo videos =D, segundo a pesar que si tengo conocimiento en dependencia circulares en DB no sé me hace fácil entender la solución que dan en este curso, me gustaría si fuera posible que nos diera una respuesta más detallada. Me explico entiendo que siempre tenemos que evitar las tranferencia circulares o inyecciones circulares esto igual ocurre a nivel de base de datos. En nivel de base de datos siempre se busca generar entidades que no tengan estas dependencias, por lo cual la solucion es simple, nunca crear una dependencia circular. Pero en el caso mostrado en los servicio no entiendo cual es el efecto de tener esta inyeccion circular, y si fuera el mismo problema que existe en la DB (¿debo considerar que este problema viene de las dependencia circulares de la BD o son distintas?), no entiendo como haciendo un modulo global soluciona el problema ya que los servicios van a funcionar de las misma manera. Gracias.
creando un modulo para conexión a Base de datos, sera un global module
No entiendo, y no solo desde el app.module ponia en exports los providers y listo? para que crear un modulo aparte y hacerlo global?
Saludos, excelente clase, tengo una duda, cuando se usa el Global Module, en el archivo app.module, sería necesario importarlo allí también? ¿o es opcional?
No es necesario importar el módulo global en app.module; se importa automáticamente en todos los módulos de la aplicación.
¿Global Module sería un observer pattern como lo es Redux?
Estoy utilizando enums, para evitar los magic strings como "API_KEY" y asi asegurarme que estoy mandando el string correcto
este concepto de modulo global si está relacionado con el design pattern singlenton.
En la clase de inyeccion de dependencias creo que se referia mas a la D de SOLID, que significa Dependency Inversion Principle, que tambien abarca la inyeccion de dependencias, pues esto permite que la dependencia sea una interface y evita que sea creada una instancia dentro de la clase dependiente, evitando asi el acomplamiento.