Tipos de Providers en NestJS: Use Class y Use Value
Resumen
NestJS posee diferentes formas de inyectar servicios en un módulo según la necesidad. Exploremos algunas de ellas, sus diferencias y cuándo utilizarlas.
Cómo hacer la inyección con "useClass"
Cuando realizas un import de un servicio en un módulo:
Ambas sintaxis son equivalentes, useClass es el tipo de inyección por defecto. Básicamente, indica que un servicio debe utilizar X clase para funcionar. Si el día de mañana, por algún motivo en tu aplicación, el servicio AppService queda obsoleto y tienes que reemplazarlo por uno nuevo, puedes realizar lo siguiente:
De este modo, no tienes necesidad de cambiar el nombre AppService en todos los controladores donde se utiliza, este será reemplazado por la nueva versión del servicio.
Cómo hacer la inyección con "useValue"
Además de clases, puedes inyectar valores como un string o un número. useValue suele utilizarse para inyectar globalmente en tu aplicación la llave secreta de una API o alguna otra variable de entorno que tu app necesita.
Para esto, simplemente inyecta el valor de una constante en el providers.
Para los que usan windows y powershell una manera de setear la variable antes del comando es así:
$env:NODE_ENV='prod'; npm run start:dev
Dependiendo del sistema operativo y la terminal la manera de hacerlo cambio, hay paquetes en npm que nos ayudan a setear variables sin importar la plataforma, como por ejemplo
cross-env
Para inyectar un .env en el proceso pueden usar el paquete dotenv-cli.
gracias crack
Resumen
Introducción
Cuando queremos que la instancia de una clase se comparta por todo un modulo debemos hacer 2 cosas.
Le colocamos el decorador @Inyectable a la clase
@Injectable()// <-- El decoradorexportclassProductsService{// ...}
Y lo declaramos dentro del modulo correspondiente usando la sintaxis resumida
@Module({...providers:[...,ProductsService],// Aqui por ejemplo...})
useClass
Internamente, nest js rescribe esta sintaxis de la siguiente forma:
@Module({...providers:[...,{provide:ProducsService,// Nombre con el que haremos referencia a ellauseClass:ProducsService// Nombre de la clase que se usara}],// Aqui por ejemplo...})
useValues
Además de poder inyectar clases también podemos inyectar valores. Esto es util para compartir valores que globales de la aplicación y evita que estos se guarden en memoria cada vez que se requieran.
constAPI_KEY='12345634';constAPI_KEY_PROD='PROD1212121SA';@Module({imports:[...],controllers:[..],providers:[AppService,{provide:'API_KEY',// Nombre con el que se hara referenciauseValue: process.env.NODE_ENV==='prod'?API_KEY_PROD:API_KEY,// El valor},],})exportclassAppModule{}
Buen apunte!!
Agrego que al momento de ejecutar la app hay que ponele la variable de entorno.
NODE_ENV=prod npm run start:dev
@wlensinas Excelente complemento
No creo que sea buena practica dejar quemado en código los datos de conexión a una base de datos.
.
Todas estas variables que se utilizan con useValue vendrian a ser las variables de entorno que en aplicaciones con express se almacenan en un archivo .env
Hola Alejandro, si tienes razón y esta parte la vemos más adelante en el curso.
No recomendaría usar if...else o ternary operators sobre NODE_ENV en el código como tal, usualmente en un ambiente productivo tendrías un .env por cada ambiente, o en el caso de NestJS, @nestjs/config, y que eso cargue las variables acorde al entorno.
Aunque en el curso no se toca esta parte, el uso de los provide useClass y useValue se usan mucho en los test unitarios
Cuando se va a hacer el test unitario de un controller se debe usar una dumy class del servicio porque el objetivo del test es comprobar solo los metodos del controller y en este caso se remplaza la clase original por otra que tiene una implementación falsa para el caso de un UsersService seria algo asi
Qué ventaja usar estas inyecciones sobre usar directamente el "process.env" ??
Cual seria la diferencia de ocupar unseValue con dejar un archivo .ts con todas mis constantes y que la pueda llamar desde cualquier parte de mi proyecto ?
Tengo una duda al respecto, la variable que injectamos solo tiene la propiedad de solo lectura? o tambien se puede sobreescribir una vez injectado?. Claro si no es declarado como constante.
Es una buena práctica siempre declarar el provider que vamos a inyectar como readonly para evitar una reasignación
En que caso podria usar o ser buena practica usar useValue ?
Revise decenas de veces el código, idéntico al del profesor, y no funcionaba, levante y baje el servidor hasta que a la hora de prueba y prueba, funciono... Me decepciona mucho NestJS de momento....
Que raro de pronto algo en el ambiente o código estaba incorrecto, si me compartes tu repo o lo que estás intentando hacer te puedo ayudar. 😃
A mi me encanta Nestjs xD, si quieres puedes comparar tu codigo con la consola usando diff -r :D
Si están usando Ubuntu, tiene que exportar la variable:export NODE_ENV=development```js
export NODE_ENV=prod
```js
unset NODE_ENV
Tambien podrías o pueden crear un archivo .env y definir la variable de manera global. Eso les permitiria usarlo en cualquiera modulo
Utilizando el valor en un controlador o servicio. Decorador @Inject
Use Value
Use Class
Use Value
Hola 👋
Para los usuarios de yarn, solo cambia un poco el comandos.