Préparation d'entretien 100% Gratuit angularforall.com

NestJS Junior — Guards & Middleware

Nestjs Junior Quiz-Nestjs-Junior Nestjs-Middleware Nestjs-Guards Nestjs-Intercepteurs Nestjs-Pipes Exception-Handling Questions-Entretien-Nestjs-Junior Qcm-Nestjs-Junior Typeorm Node-Js Typescript Back-End
Junior 🔀 Mixte 20 questions ⏱ 15 min
📝

NestJS Junior — Guards & Middleware

20 questions NestJS niveau junior : middleware, guards, intercepteurs, pipes, gestion des exceptions et intégration avec les bases de données. Parfait pour réussir un entretien NestJS Junior.

20 questions ⏱ ~15 min Niveau Junior

Partager

Banque de révision : les 30 questions corrigées

Voici l'intégralité des 30 questions de « NestJS Junior — Guards & Middleware », chacune avec sa bonne réponse et son explication. Le quiz interactif ci-dessus en tire une sélection aléatoire à chaque tentative — utilisez cette liste complète pour réviser.

  • Modules, Contrôleurs, Services (Providers) avec injection de dépendances (bonne réponse)
  • Models, Views, Controllers (MVC classique)
  • Components, Services, Directives (inspiré Angular)
  • Routes, Handlers, Middlewares (Express pur)
Explication : NestJS organise l'application en modules (@Module), contrôleurs (@Controller) pour les routes, et services/providers (@Injectable) pour la logique métier. L'injection de dépendances lie le tout de manière découplée.
Cette architecture modulaire rend le code testable, maintenable et évolutive pour des projets backend complexes.

  • Créer un module avec exports: [MonService] et l'importer dans les autres modules
  • Déclarer le service dans chaque module séparément
  • Utiliser @Global() pour rendre le module global
  • Les deux réponses A et C sont correctes selon le besoin (bonne réponse)
Explication : Deux approches : 1) Module standard avec exports: [MonService] qu'on importe dans chaque module qui en a besoin. 2) Module global avec @Global() qui rend ses exports disponibles partout sans import. L'approche standard est préférable par défaut.
Exemple : @Module({ providers: [MonService], exports: [MonService] }) export class SharedModule {}

  • nest generate service users
  • nest g s users
  • nest g service users
  • Toutes ces commandes sont valides (bonne réponse)
Explication : Toutes ces commandes fonctionnent. nest generate service users ou sa forme courte nest g s users ou nest g service users créent un service avec son fichier de test, et l'enregistrent dans le module.
Placez le service dans un dossier : nest g s users/users crée users.service.ts dans un dossier users.

  • Utiliser ValidationPipe avec whitelist, forbidNonWhitelisted, transform (bonne réponse)
  • Appeler manuellement validate() dans le contrôleur
  • C'est automatique sans configuration
  • NestJS ne supporte pas la validation
Explication : Le ValidationPipe configuré avec whitelist: true (ignore les propriétés non définies dans le DTO), forbidNonWhitelisted: true (rejette les propriétés supplémentaires), transform: true (convertit automatiquement les types).
Activation globale : app.useGlobalPipes(new ValidationPipe({ whitelist: true, transform: true }));

  • Un provider créé avec useValue, useClass, useFactory ou useExisting pour un contrôle fin de l'injection (bonne réponse)
  • Un provider écrit manuellement sans décorateur
  • Un provider qui n'est pas injectable
  • Un service sans constructeur
Explication : Les custom providers permettent de définir comment un token est résolu : useValue (valeur constante), useClass (classe alternative), useFactory (logique de création), useExisting (alias). Utile pour les configurations, mocks en test, ou logique complexe.
Exemple : { provide: "CONFIG", useValue: { apiKey: "123" } } puis @Inject("CONFIG") config

  • app.enableCors() dans main.ts avec options optionnelles
  • Ajouter un middleware CORS manuellement
  • Installer le package cors
  • Les deux réponses A et C sont correctes (bonne réponse)
Explication : La méthode app.enableCors() active CORS avec les options par défaut. On peut passer des options : app.enableCors({ origin: "https://example.com", credentials: true }). NestJS utilise le middleware cors sous-jacent.
Pour le développement, app.enableCors() sans options autorise toutes les origines. En production, restreignez avec origin.

  • C'est strictement identique, @Request() est un alias de @Req() (bonne réponse)
  • @Req() récupère la requête Express, @Request() récupère la requête Fastify
  • @Req() est pour GET, @Request() pour POST
  • @Req() est déprécié
Explication : Les deux décorateurs sont identiques et interchangeables. @Req() est la forme courte, @Request() la forme longue. Ils injectent l'objet natif de la requête (Express ou Fastify selon le moteur).
Préférez les décorateurs spécifiques comme @Body(), @Param(), @Query() plutôt que @Req() pour un code plus propre.

  • @Redirect("https://example.com", 301)
  • res.redirect()
  • @HttpRedirect("https://example.com")
  • Les deux réponses A et B sont correctes (bonne réponse)
Explication : On peut utiliser le décorateur @Redirect() au-dessus de la méthode, ou appeler res.redirect() en injectant l'objet réponse avec @Res(). Le décorateur est plus déclaratif.
Exemple : @Get() @Redirect("https://nestjs.com", 301) redirect() { return; }

  • Un module qui charge les variables d'environnement depuis .env et fournit un ConfigService typé (bonne réponse)
  • Un module de configuration des routes
  • Un module de logging
  • Un module de base de données
Explication : @nestjs/config utilise dotenv sous le capot. Il charge les variables d'environnement depuis .env, permet la validation avec Joi, et fournit ConfigService pour y accéder de manière typée et testable.
Installation : npm install @nestjs/config. Importez ConfigModule.forRoot() dans AppModule.

  • app.setGlobalPrefix("api") dans main.ts (bonne réponse)
  • @GlobalPrefix("api") dans AppModule
  • dans le fichier nest-cli.json
  • impossible, il faut le faire par contrôleur
Explication : La méthode app.setGlobalPrefix("api") ajoute un préfixe à toutes les routes de l'application. Les routes deviennent /api/users, /api/products, etc.
Pour exclure certaines routes, utilisez app.setGlobalPrefix("api", { exclude: ["health"] }).

  • Versioning intégré via @Controller({ version: "1" }) et app.enableVersioning() (bonne réponse)
  • Ajouter /v1/ dans les routes manuellement
  • NestJS ne supporte pas le versioning
  • Utiliser des branches Git différentes
Explication : NestJS 8+ supporte le versioning natif. On active app.enableVersioning() (type URI, Header, Media Type). Ensuite, @Controller({ version: "1" }) ou @Version("1") sur une méthode.
Stratégies : VERSION_URI (/v1/users), VERSION_HEADER (en-tête personnalisé), VERSION_MEDIA_TYPE (Accept header).

  • Quand deux modules ou services s'importent mutuellement ; résoudre avec forwardRef(() => Module/Service) (bonne réponse)
  • Une boucle infinie dans le code
  • Une erreur de compilation
  • Une dépendance qui n'existe pas
Explication : Une dépendance circulaire survient quand ModuleA importe ModuleB et ModuleB importe ModuleA (ou ServiceA injecte ServiceB et ServiceB injecte ServiceA). Solution : forwardRef(() => ModuleB) dans les imports et @Inject(forwardRef(() => ServiceB)).
Préférez restructurer le code. forwardRef est une solution de dernier recours qui a un léger impact sur les performances.

  • Créer une classe qui étend HttpException et appelle super(message, statusCode) (bonne réponse)
  • Utiliser throw new Error()
  • Créer une classe qui implémente ExceptionFilter
  • NestJS ne permet pas les exceptions personnalisées
Explication : Pour créer une exception personnalisée : export class ForbiddenException extends HttpException { constructor() { super("Forbidden", HttpStatus.FORBIDDEN); } }. On peut aussi étendre les exceptions intégrées comme NotFoundException.
On peut ajouter des propriétés personnalisées via super("Message", status, { cause: error }).

  • Un décorateur créé avec createParamDecorator pour extraire des données spécifiques de la requête (ex: utilisateur courant) (bonne réponse)
  • Un décorateur pour les classes
  • Un décorateur pour les modules
  • Un alias pour @Injectable()
Explication : Les custom decorators permettent de créer ses propres décorateurs de paramètres. Exemple : @CurrentUser() qui extrait l'utilisateur du token JWT. Utilise createParamDecorator() et ExecutionContext.
Exemple : export const CurrentUser = createParamDecorator((data, ctx) => { const req = ctx.switchToHttp().getRequest(); return req.user; });

  • Importer TypeOrmModule.forRoot() dans AppModule, créer des entities, et injecter le repository (bonne réponse)
  • Installer pg et écrire du SQL brut
  • Utiliser Mongoose pour PostgreSQL
  • NestJS ne supporte pas PostgreSQL
Explication : NestJS s'intègre nativement avec TypeORM via @nestjs/typeorm. On configure TypeOrmModule.forRoot() avec les options de connexion, on définit des entités, et on injecte les repositories avec @InjectRepository(Entity).
Installation : npm install @nestjs/typeorm typeorm pg. TypeORM supporte MySQL, PostgreSQL, SQLite, MongoDB, etc.

  • Charger des modules uniquement quand une route spécifique est appelée (réduction du temps de démarrage) (bonne réponse)
  • Un mode de développement plus lent
  • Une technique de mise en cache
  • Un type de base de données
Explication : Le lazy loading permet de charger des modules dynamiquement avec import(). Utile pour les modules administratifs, les fonctionnalités rarement utilisées, ou les microservices. Réduit le bundle initial et le temps de démarrage.
Exemple : const module = await import("./admin/admin.module"); const AdminModule = module.AdminModule;

  • Utiliser @nestjs/jwt et @nestjs/passport, créer un strategy JWT, et un guard AuthGuard("jwt") (bonne réponse)
  • Écrire son propre middleware d'authentification
  • Utiliser session express
  • NestJS n'a pas de support JWT intégré
Explication : NestJS s'intègre avec Passport.js via @nestjs/passport. On crée une stratégie JWT (extrait le token du header, vérifie la signature), et on utilise @UseGuards(AuthGuard("jwt")) sur les routes protégées.
Installation : npm install @nestjs/jwt @nestjs/passport passport passport-jwt. Configurez la clé secrète et les options.

  • Fichier de configuration de la CLI NestJS (chemin des sources, compilateur, assets) (bonne réponse)
  • Le point d'entrée de l'application
  • La configuration du serveur
  • Un fichier généré automatiquement sans importance
Explication : nest-cli.json configure le comportement de la CLI : sourceRoot (dossier source), compilerOptions (webpack, tsconfig), assets (fichiers à copier dans le build), monorepo (configuration multi-projets).
Généré automatiquement par nest new. On peut le modifier pour personnaliser les générateurs, les entrées, etc.

  • Utiliser onModuleInit() ou onApplicationBootstrap() dans un service ou module
  • Ajouter du code dans main.ts avant app.listen()
  • Utiliser @OnStart()
  • Les deux réponses A et B sont correctes (bonne réponse)
Explication : Deux approches : 1) Implémenter OnModuleInit ou OnApplicationBootstrap dans un service (exécution garantie après l'injection). 2) Code synchrone dans main.ts avant app.listen() (mais sans accès aux services injectés).
Préférez OnModuleInit pour les initialisations qui dépendent des services injectés.

  • Un provider qui crée une nouvelle instance pour chaque requête HTTP (bonne réponse)
  • Un provider accessible uniquement dans la requête
  • Un provider qui partage l'état entre plusieurs requêtes
  • Un provider qui s'exécute à chaque requête
Explication : Les providers Request Scoped (@Injectable({ scope: Scope.REQUEST })) créent une nouvelle instance par requête. Utile pour stocker des données liées à la requête (utilisateur courant, tenant ID). Attention : impact sur les performances.
À utiliser avec parcimonie. Préférez passer l'utilisateur via les paramètres de méthode plutôt que via l'état du service.

  • Installer @nestjs/swagger, ajouter les décorateurs (@ApiTags, @ApiOperation, @ApiResponse), et setupSwagger dans main.ts (bonne réponse)
  • Écrire la documentation manuellement
  • Utiliser JSDoc
  • NestJS n'a pas d'intégration Swagger
Explication : NestJS a une excellente intégration Swagger : @nestjs/swagger analyse les contrôleurs et DTOs. On ajoute des décorateurs @ApiProperty() dans les DTOs, @ApiOperation() sur les méthodes, et on configure SwaggerModule.setup() dans main.ts.
La documentation générée est accessible sur /api (par défaut). Les décorateurs améliorent la lisibilité.

  • Des interfaces qui permettent d'exécuter du code à différentes étapes du cycle de vie (init, bootstrap, shutdown) (bonne réponse)
  • Des hooks pour les requêtes HTTP
  • Des méthodes automatiques des contrôleurs
  • Des hooks pour les tests
Explication : NestJS fournit plusieurs hooks de cycle de vie : OnModuleInit, OnModuleDestroy, OnApplicationBootstrap, OnApplicationShutdown, BeforeApplicationShutdown. Utiles pour initialiser des connexions, nettoyer des ressources, etc.
Pour le shutdown, l'application doit avoir été créée avec app.enableShutdownHooks() pour écouter les signaux SIGTERM/SIGINT.

  • Utiliser app.useStaticAssets() dans main.ts (Express) ou fastify-static (Fastify) (bonne réponse)
  • Les mettre dans src/static
  • Utiliser @Static()
  • NestJS ne sert pas de fichiers statiques
Explication : Avec Express : app.useStaticAssets(join(__dirname, "..", "public")). Avec Fastify : app.register(require("@fastify/static"), { root: publicDir }). Les fichiers sont accessibles directement.
Placez les fichiers statiques dans un dossier public à la racine du projet. En production, utilisez un reverse proxy (Nginx).

  • Une classe implémentant PipeTransform avec transform(value, metadata) (bonne réponse)
  • Une fonction qui modifie la requête
  • Un middleware spécial
  • Un type de guard
Explication : Un custom pipe implémente PipeTransform et sa méthode transform(value, metadata). Il peut transformer la valeur (ex: string en number) ou valider (lancer BadRequestException).
Exemple : @Injectable() class ParseIntPipe implements PipeTransform { transform(value: string) { const val = parseInt(value); if (isNaN(val)) throw new BadRequestException(); return val; } }

  • Utiliser Test.createTestModule() avec l'application réelle, et supertest pour les requêtes HTTP (bonne réponse)
  • Utiliser uniquement des tests unitaires
  • Lancer l'application et appeler l'API manuellement
  • NestJS n'a pas de support e2e
Explication : NestJS utilise @nestjs/testing pour créer une application de test, et supertest pour envoyer des requêtes HTTP. On peut utiliser la base de données réelle ou un conteneur Docker.
Exemple : const app = await Test.createTestingModule({ imports: [AppModule] }).compile(); const request = supertest(app.getHttpServer());

  • Une classe implémentant ExceptionFilter avec catch(exception, host) ; global avec app.useGlobalFilters() (bonne réponse)
  • Un try/catch dans chaque contrôleur
  • Un middleware qui capture les erreurs
  • NestJS n'a pas de filtres d'exception
Explication : Les exception filters interceptent les exceptions non capturées. Un custom filter implémente ExceptionFilter. On l'applique globalement avec app.useGlobalFilters(new MyFilter()) ou localement avec @UseFilters().
Utile pour formater les erreurs, logger, ou envoyer des réponses personnalisées (ex: format standard d'API).

  • Utiliser TypeOrmModule.forRoot() multiple fois avec des noms différents (name) (bonne réponse)
  • Impossible, une seule base par application
  • Utiliser des modules séparés
  • Créer deux applications distinctes
Explication : TypeORM supporte plusieurs connexions. Dans NestJS, on utilise TypeOrmModule.forRoot({ name: "db1", ... }) et TypeOrmModule.forRoot({ name: "db2", ... }). Pour injecter un repository : @InjectRepository(Entity, "db1").
Utile pour la séparation lecture/écriture, ou pour connecter plusieurs bases (utilisateurs, produits, logs).

  • Un décorateur qui utilise Reflector pour lire les métadonnées définies par @SetMetadata() (bonne réponse)
  • Un décorateur pour les paramètres
  • Un décorateur pour les classes
  • Un alias pour @Injectable()
Explication : Les custom decorators peuvent utiliser Reflector pour accéder aux métadonnées. Exemple : @Roles("admin") définit des métadonnées, un guard peut les lire avec reflector.get("roles", context.getHandler()).
Pattern courant : décorateur @Roles() pour la sécurité basée sur les rôles, combiné avec un guard AuthGuard.

  • npm run build, puis pm2 start dist/main.js (bonne réponse)
  • nest start --prod
  • node dist/main.js
  • pm2 start nest
Explication : En production : 1) npm run build compile dans dist/. 2) pm2 start dist/main.js démarre avec PM2 (process manager). PM2 gère les redémarrages, les logs, le clustering.
Utilisez pm2 ecosystem.config.js pour configurer les variables d'environnement, le nombre d'instances (cluster), et les scripts de démarrage.

  • Un module d'intégration pour MongoDB avec Mongoose ODM, similaire à TypeOrmModule (bonne réponse)
  • Un module pour PostgreSQL
  • Un module pour Redis
  • Un module de logging
Explication : @nestjs/mongoose permet d'intégrer MongoDB avec Mongoose. On utilise MongooseModule.forRoot() pour la connexion, @Schema() et @Prop() pour les schémas, et @InjectModel() pour injecter les modèles.
Installation : npm install @nestjs/mongoose mongoose. Alternative à TypeORM pour MongoDB (TypeORM supporte aussi MongoDB mais Mongoose est plus mature).