loading...

No olvides exportar los providers en NestJS

imsergiobernal profile image Sergio ・2 min read

Si ya conoces NestJS, sabrás que tiene mucha similitud con el framework de front-end Angular. Y no es pura casualidad, dado que NestJS basa gran parte de su arquitectura en librerías del propio Angular.

Si estás comenzando con NestJS, es muy importante que centres energías en aprender cómo funciona el mecanismo de contenedores de Inversión de Control. A su vez, has de saber que se parece bastante al mecanismo de Angular pero no son exactamente iguales.

Por ejemplo, en Angular encontramos un artefacto llamado Component (decorador @component) mientras que en Nest tenemos un artefacto llamado Controller (decorador @controller) que vendría a ser un parecido. Esto se debe a que Nest no tiene que lidiar con temas de view rendering y se centra directamente en el concepto de controlador.

Vamos a hacer un repaso a la interfaz que tienen los decoradores @NgModule y @Module en cada framework —Angular y Nest respectivamente.

// Angular front-end AdminModule
@NgModule({
  declarations: [MyComponent, MyDirective, MyPipe],
  entryComponents: [],
  providers: [MyService], // imported and auto-public for everyone
  imports: [AdminDashboardModule],
  exports: [MyComponent, MyDirective, MyPipe]
})
export default class AdminModule {};

// Nest back-end AdminModule
@Module({
  providers: [MyService, MyRepository, MyFactory, MyHelper],
  controllers: [AdminController],
  imports: [CoreModule],
  exports: [AdminService, MyService/*re-export needed to be public for the enquirer*/]
})
export default class AdminModule {}

Comparando interfaces de los módulos en Angular y Nest

Vamos a hablar en concreto de la propiedad exports en ambos frameworks.

Propiedad exports

En Nest, la propiedad export en un @Module define qué Providers serán expuestos hacia el módulo que lo está importando, también llamado enquirer.

  ...
  providers: [MyService, MyRepository, MyFactory, MyHelper],
  exports: [MyService, MyRepository] // Es necesario exportar para hacerlo público
  ...

Recordemos. Un Provider es aquel elemento que puede ser inyectado como dependencia. Ejemplos de Providers son: servicios, repositorios, factories, helpers, etc.

Mientras que en Angular, la propiedad export en un @NgModule permite listar qué declaraciones—componentes, directivas y pipes— serán expuestas. Todo Provider en la propiedad providers será público y accesible en toda la aplicación bootstrapeada.

  ...
  providers: [MyService], // Serán públicos automáticamente
  ...

Exceptuando aquel módulo que sea Lazy Loaded dado que tendrá su propio lazy loaded injector.

Lo importante de esto es que sepas que en Nest has de especificar qué Providers quieres que sean públicos, ya que por defecto no se exportará ninguno. Esto es una gran diferencia con Angular por que en dicho framework, los Providers son registrados en el módulo root/root injector de toda la aplicación—accesible por lo tanto por todos los módulos—.

El objetivo en Nest es encapsular y aislar 📦 por completo todos los Providers del Module. Pero, si quieres que alguno sea público para quien importe dicho módulo, entonces deberás especificarlo en la propiedad exports.

cats.module.ts 🐈

import { Module } from '@nestjs/common';
import { CatsController } from './cats.controller';
import { CatsService } from './cats.service';

@Module({
  controllers: [CatsController],
  providers: [CatsService],
  exports: [CatsService] // hago CatsService público!
})
export class CatsModule {}

Espero que este recordatorio y explicación te sean de utilidad en tu proyecto de Nest 🧐.

Discussion

markdown guide
 

Buena recomendación. Gracias, estoy recién iniciando con nest.