d · Gérer la configuration
- Projet : Loup-Garou
- Environ 35 minutes
- 3 exercices
Depuis la partie 3, main.ts lit process.env.PORT directement. Ça fonctionne, mais rien ne dit ce que ton application attend comme variables d’environnement, ni ne prévient si l’une d’elles manque. @nestjs/config structure ça.
npm install @nestjs/configPORT=3000NOMBRE_MAX_VILLAGES=50ConfigModule.forRoot({ isGlobal: true }) lit ce fichier au démarrage, et rend ConfigService injectable partout dans l’application :
import { Module } from '@nestjs/common';import { ConfigModule } from '@nestjs/config';
@Module({ imports: [ConfigModule.forRoot({ isGlobal: true }), /* … */],})export class AppModule {}import { NestFactory } from '@nestjs/core';import { ValidationPipe } from '@nestjs/common';import { ConfigService } from '@nestjs/config';import { AppModule } from './app.module.js';
async function bootstrap() { const app = await NestFactory.create(AppModule); app.useGlobalPipes(new ValidationPipe()); const config = app.get(ConfigService); await app.listen(config.get('PORT') ?? 3000);}await bootstrap();ConfigService s’injecte aussi dans un service, exactement comme n’importe quel autre provider — plus besoin de toucher à process.env où que ce soit dans ton code :
@Injectable()export class VillagesService { constructor(private readonly config: ConfigService) {}
creer(dto: CreerVillageDto) { const maximum = this.config.get<number>('NOMBRE_MAX_VILLAGES'); // … }}Valider les variables d’environnement
Section intitulée « Valider les variables d’environnement »Un .env incomplet plante silencieusement plus tard, au premier undefined inattendu — bien après le démarrage. L’option validate de ConfigModule.forRoot vérifie tout avant, avec les décorateurs de la section b :
import { IsNumber, Min } from 'class-validator';import { plainToInstance } from 'class-transformer';import { validateSync } from 'class-validator';
class VariablesEnvironnement { @IsNumber() PORT: number = 3000;
@IsNumber() @Min(1) NOMBRE_MAX_VILLAGES: number;}
export function validerEnvironnement(config: Record<string, unknown>) { const validees = plainToInstance(VariablesEnvironnement, config, { enableImplicitConversion: true }); const erreurs = validateSync(validees, { skipMissingProperties: false }); if (erreurs.length > 0) throw new Error(erreurs.toString()); return validees;}ConfigModule.forRoot({ isGlobal: true, validate: validerEnvironnement }),Retire NOMBRE_MAX_VILLAGES du .env, et le serveur refuse de démarrer — au lieu de démarrer normalement et d’échouer beaucoup plus tard, en pleine requête.
Exercices 4.11 à 4.13
Projet : marketplaceInstalle @nestjs/config, ajoute ConfigModule.forRoot({ isGlobal: true }) à AppModule. Crée un .env avec PORT et NOMBRE_MAX_PRODUITS. Fais lire PORT par main.ts via ConfigService, à la place de process.env.PORT direct.
Injecte ConfigService dans ProduitsService. Dans la méthode qui crée un produit, refuse-la (avec BadRequestException) si le nombre de produits existants a atteint NOMBRE_MAX_PRODUITS. Vérifie avec une petite valeur (par exemple 1) que la création échoue dès que la limite est atteinte : comme ta marketplace contient déjà quelques produits, c’est la toute prochaine création qui échoue, pas la deuxième.
Ajoute validerEnvironnement (ci-dessus, avec NOMBRE_MAX_PRODUITS à la place de NOMBRE_MAX_VILLAGES) à ConfigModule.forRoot. Retire temporairement NOMBRE_MAX_PRODUITS de ton .env, et relance le serveur : note le message d’erreur exact au démarrage. Remets la variable pour que l’application redémarre normalement.
Pour vérifier ton travail : npm run test:partie-4 (dépôt d'exercices)