NestJS 83 termes

83 termes affichés

TypeConcept Method Pattern Principle Security Tool
Niveau 🟢 Junior 🟡 Mid 🔴 Senior

@Body

NestJS 🟢 Junior

Decorateur de parametre qui extrait le corps de la requete HTTP et le mappe sur un DTO. Peut cibler une propriete specifique avec @Body('key').

Comme ouvrir un colis et en extraire le contenu pour le traiter.

@Post()
create(@Body() dto: CreateUserDto) {
  return this.userService.create(dto);
}

@Post('login')
login(@Body('email') email: string) {
  return this.authService.login(email);
}

Cas d'usage : Recevoir les donnees envoyees par le client dans les requetes POST, PUT ou PATCH.

#core#interview

@Get/@Post/@Put/@Delete/@Patch

NestJS 🟢 Junior

Decorateurs de methode qui mappent les methodes HTTP aux handlers du controller. Chacun definit le verbe HTTP et le chemin optionnel de la route.

Comme les panneaux directionnels dans un aeroport : chacun oriente vers la bonne porte d'embarquement.

@Controller('items')
export class ItemController {
  @Get() findAll() { /* ... */ }
  @Post() create(@Body() dto: CreateItemDto) { /* ... */ }
  @Put(':id') update(@Param('id') id: string) { /* ... */ }
  @Delete(':id') remove(@Param('id') id: string) { /* ... */ }
}

Cas d'usage : Definir les operations CRUD standard sur une ressource REST.

Anti-pattern : Utiliser @Post pour des operations de lecture ou @Get avec un body de requete.
#core#interview

@Headers

NestJS 🟢 Junior

Decorateur de parametre qui extrait les headers HTTP de la requete. Peut cibler un header specifique par nom ou recuperer tous les headers.

Comme lire l'etiquette sur un colis pour connaitre l'expediteur et le contenu.

@Get()
getData(@Headers('authorization') auth: string) {
  return this.service.getData(auth);
}

Cas d'usage : Extraire les tokens d'authentification, API keys ou headers custom des requetes.

#core

@Inject

NestJS 🟡 Mid

Decorateur qui specifie le token d'injection pour un parametre de constructeur. Necessaire pour les providers enregistres avec un token string ou symbol.

Comme preciser le nom exact du fournisseur quand il y a plusieurs pour le meme type de service.

@Injectable()
export class AppService {
  constructor(
    @Inject('DATABASE_CONNECTION')
    private db: Connection,
  ) {}
}

Cas d'usage : Injecter des providers enregistres avec useValue/useFactory qui utilisent des tokens string.

#core

@Injectable

NestJS 🟢 Junior

Decorateur qui marque une classe comme injectable par le conteneur DI de NestJS. Obligatoire pour tout provider qui participe a l'injection de dependances.

Comme un badge professionnel : sans lui, le systeme ne te reconnait pas comme employe.

@Injectable()
export class AppService {
  getHello(): string {
    return 'Hello World!';
  }
}

Cas d'usage : Annoter chaque service, guard, interceptor, pipe et tout provider custom.

Anti-pattern : Oublier @Injectable sur un service qui injecte d'autres dependances, causant une erreur runtime.
#core#interview

@Param

NestJS 🟢 Junior

Decorateur de parametre qui extrait les parametres de route de l'URL (ex: /users/:id). Peut cibler un parametre specifique ou recuperer tous les params.

Comme lire le numero de chambre sur la cle d'hotel pour savoir ou aller.

@Get(':id')
findOne(@Param('id', ParseIntPipe) id: number) {
  return this.userService.findOne(id);
}

Cas d'usage : Extraire les identifiants de ressources ou slugs depuis les URLs REST.

#core

@Query

NestJS 🟢 Junior

Decorateur de parametre qui extrait les query parameters de l'URL (ex: ?page=1&limit=10). Supporte la transformation via pipes.

Comme les filtres de recherche sur un site e-commerce : ils affinent les resultats sans changer la page.

@Get()
findAll(
  @Query('page', new DefaultValuePipe(1), ParseIntPipe) page: number,
  @Query('limit', new DefaultValuePipe(10), ParseIntPipe) limit: number,
) { return this.service.paginate(page, limit); }

Cas d'usage : Implementer la pagination, le tri et le filtrage sur les endpoints de liste.

#core

@SetMetadata

NestJS 🟡 Mid

Decorateur qui attache des metadonnees personnalisees a un handler ou controller, lisibles via Reflector dans les guards ou interceptors.

Comme coller une etiquette 'VIP' ou 'Public' sur une porte pour que le vigile sache qui laisser entrer.

export const Roles = (...roles: string[]) =>
  SetMetadata('roles', roles);

@Post()
@Roles('admin')
create() { /* ... */ }

Cas d'usage : Definir les roles requis sur un endpoint pour les verifier dans un RolesGuard.

#core#security

@UseFilters

NestJS 🟡 Mid

Decorateur qui attache un ou plusieurs filtres d'exception a un controller ou handler pour intercepter et formater les erreurs specifiques.

Comme un traducteur qui reformule les erreurs techniques en messages comprehensibles pour le client.

@Controller('users')
@UseFilters(new HttpExceptionFilter())
export class UserController {
  @Post()
  create(@Body() dto: CreateUserDto) {
    return this.service.create(dto);
  }
}

Cas d'usage : Appliquer un format d'erreur personnalise pour un domaine specifique de l'API.

#core

@UseGuards

NestJS 🟡 Mid

Decorateur qui attache un ou plusieurs guards a un controller ou un handler. Les guards s'executent avant le handler pour autoriser ou refuser l'acces.

Comme placer un vigile devant une porte specifique ou a l'entree de tout le batiment.

@Controller('admin')
@UseGuards(AuthGuard, RolesGuard)
export class AdminController {
  @Get('dashboard')
  getDashboard() { return 'admin data'; }
}

Cas d'usage : Proteger un controller entier ou des routes specifiques avec authentification et autorisation.

#core#security

@UseInterceptors

NestJS 🟡 Mid

Decorateur qui attache un ou plusieurs interceptors a un controller ou handler pour transformer les requetes/reponses ou ajouter des comportements transversaux.

Comme ajouter un filtre Instagram a une photo : le contenu est le meme mais la presentation change.

@Controller('users')
@UseInterceptors(CacheInterceptor)
export class UserController {
  @Get()
  @UseInterceptors(ClassSerializerInterceptor)
  findAll() { return this.service.findAll(); }
}

Cas d'usage : Appliquer la serialisation, le cache ou le logging sur des routes specifiques.

#core

@UsePipes

NestJS 🟡 Mid

Decorateur qui attache un ou plusieurs pipes a un controller ou handler pour valider ou transformer les donnees entrantes automatiquement.

Comme un detecteur de metaux a l'entree : il filtre automatiquement tout ce qui n'est pas conforme.

@Post()
@UsePipes(new ValidationPipe({ whitelist: true }))
create(@Body() dto: CreateUserDto) {
  return this.service.create(dto);
}

Cas d'usage : Activer la validation automatique des DTOs avec class-validator sur des routes specifiques.

#core

ABAC

NestJS 🔴 Senior

Attribute-Based Access Control : systeme d'autorisation base sur les attributs du sujet, de la ressource et du contexte. Plus flexible que RBAC.

Comme une boite de nuit avec des regles complexes : age + tenue + liste VIP + heure determinant l'acces.

// Regle ABAC: l'auteur peut modifier son propre article
canActivate(ctx: ExecutionContext) {
  const user = ctx.switchToHttp().getRequest().user;
  const articleId = ctx.switchToHttp().getRequest().params.id;
  const article = await this.articleService.findOne(articleId);
  return article.authorId === user.id;
}

Cas d'usage : Implementer des regles d'autorisation fines comme 'un auteur ne peut modifier que ses propres articles'.

#security

BullModule

NestJS 🟡 Mid

Module pour gerer des queues de jobs asynchrones via Redis et Bull/BullMQ. Permet le traitement en arriere-plan avec retries et scheduling.

Comme une file d'attente au guichet : les taches arrivent, sont traitees dans l'ordre et reessayees si besoin.

@Processor('email')
export class EmailProcessor {
  @Process()
  async sendEmail(job: Job<EmailData>) {
    await this.mailer.send(job.data);
  }
}

// Ajout en queue
await this.emailQueue.add({ to: 'user@mail.com', subject: 'Hello' });

Cas d'usage : Traiter l'envoi d'emails, le redimensionnement d'images ou les exports CSV en arriere-plan.

Anti-pattern : Traiter des taches longues de facon synchrone dans le request handler, bloquant la reponse.
#core

CacheModule

NestJS 🟡 Mid

Module de cache integre qui supporte le cache en memoire ou via des stores externes (Redis). Utilise des interceptors pour cacher les reponses automatiquement.

Comme un post-it avec les reponses frequentes : plus rapide que de recalculer a chaque fois.

@Module({
  imports: [CacheModule.register({
    store: redisStore,
    host: 'localhost',
    ttl: 60,
  })],
})
export class AppModule {}

@UseInterceptors(CacheInterceptor)
@Get()
findAll() { return this.service.findAll(); }

Cas d'usage : Cacher les reponses de endpoints lourds comme les listes avec pagination pour reduire la charge DB.

Anti-pattern : Cacher des donnees sensibles ou mutables sans strategie d'invalidation.
#core

CASL

NestJS 🔴 Senior

Librairie d'autorisation isomorphe qui definit les abilities (permissions) de facon declarative. S'integre avec NestJS via un guard custom.

Comme un reglement interieur detaille : chaque personne sait exactement ce qu'elle peut et ne peut pas faire.

const ability = defineAbility((can, cannot) => {
  can('read', 'Article');
  can('update', 'Article', { authorId: user.id });
  cannot('delete', 'Article');
});
// ability.can('update', article) -> true/false

Cas d'usage : Gerer des permissions granulaires avec des conditions sur les champs des entites.

#security

Circular Dependency

NestJS 🟡 Mid

Situation ou deux providers ou modules dependent mutuellement l'un de l'autre, causant une erreur de resolution. Se resout avec forwardRef.

Comme deux personnes bloquees a une porte, chacune attendant que l'autre passe en premier.

// Module A importe B, B importe A
@Module({
  imports: [forwardRef(() => ModuleB)],
})
export class ModuleA {}

Cas d'usage : Resoudre temporairement une dependance circulaire tout en planifiant un refactoring pour l'eliminer.

Anti-pattern : Accepter les dependances circulaires comme normales au lieu de repenser l'architecture.
#core#interview

ClientProxy

NestJS 🔴 Senior

Abstraction pour communiquer avec d'autres microservices via send() (request-reply) ou emit() (event-based). Injectee via ClientsModule.

Comme un telephone interne d'entreprise : tu appelles un autre service et attends (send) ou laisses un message (emit).

@Injectable()
export class OrderService {
  constructor(@Inject('PAYMENT_SERVICE') private client: ClientProxy) {}

  processPayment(order: Order) {
    return this.client.send('process_payment', order);
  }
  notifyShipping(order: Order) {
    this.client.emit('order_shipped', order);
  }
}

Cas d'usage : Appeler des microservices distants depuis un service NestJS de facon decouple.

#architecture

ConfigModule

NestJS 🟡 Mid

Module officiel @nestjs/config pour gerer les variables d'environnement. Charge les fichiers .env et fournit ConfigService pour l'injection.

Comme un coffre-fort d'entreprise : centralise tous les secrets et parametres, accessible uniquement aux autorises.

@Module({
  imports: [ConfigModule.forRoot({
    isGlobal: true,
    validationSchema: Joi.object({
      DB_HOST: Joi.string().required(),
      DB_PORT: Joi.number().default(5432),
    }),
  })],
})
export class AppModule {}

Cas d'usage : Centraliser et valider toutes les variables d'environnement au demarrage de l'application.

Anti-pattern : Acceder directement a process.env partout au lieu d'utiliser ConfigService.
#core#interview

Connection Pooling

NestJS 🔴 Senior

Technique de reutilisation de connexions base de donnees via un pool precharge. Evite le cout de creation/destruction de connexions a chaque requete.

Comme un parc de voitures partagees : au lieu que chacun achete sa voiture, on partage un pool.

TypeOrmModule.forRoot({
  type: 'postgres',
  host: 'localhost',
  extra: {
    max: 20,
    idleTimeoutMillis: 30000,
  },
})

Cas d'usage : Optimiser les performances en production en configurant le pool selon la charge attendue.

Anti-pattern : Creer une nouvelle connexion a chaque requete sans pool, saturant la base de donnees.
#database#interview

Controller

NestJS 🟢 Junior

Classe decoree @Controller qui gere les requetes HTTP entrantes et retourne les reponses. Chaque methode est mappee a une route via des decorateurs HTTP.

Comme un receptionniste d'hotel : il recoit les demandes des clients et les redirige vers le bon service.

@Controller('users')
export class UserController {
  constructor(private userService: UserService) {}

  @Get(':id')
  findOne(@Param('id') id: string) {
    return this.userService.findOne(id);
  }
}

Cas d'usage : Definir les endpoints REST de l'API et deleguer la logique metier aux services.

Anti-pattern : Mettre de la logique metier dans le controller au lieu de la deleguer au service.
#core#interview

CORS

NestJS 🟢 Junior

Cross-Origin Resource Sharing : mecanisme HTTP qui permet a un frontend sur un domaine different d'acceder a l'API. Configure via app.enableCors().

Comme un visa d'entree : il autorise les visiteurs de certains pays (origines) a acceder au territoire (API).

app.enableCors({
  origin: ['https://monsite.com', 'https://admin.monsite.com'],
  methods: ['GET', 'POST', 'PUT', 'DELETE'],
  credentials: true,
});

Cas d'usage : Permettre au frontend SPA sur un autre domaine de communiquer avec l'API backend.

Anti-pattern : Configurer origin: '*' avec credentials: true, ce qui est interdit par les navigateurs et insecurise.
#security#interview

createTestingModule

NestJS 🟡 Mid

Methode de Test.createTestingModule qui cree un module NestJS isole pour les tests. Permet de mocker les dependances via overrideProvider.

Comme un simulateur de vol : tu recrees l'environnement complet mais en mode test.

const module = await Test.createTestingModule({
  providers: [UserService,
    { provide: UserRepository, useValue: mockRepo }],
}).compile();

const service = module.get<UserService>(UserService);
expect(await service.findAll()).toEqual([]);

Cas d'usage : Ecrire des tests unitaires et d'integration pour les services NestJS avec des mocks.

Anti-pattern : Tester les services sans TestingModule, instanciant manuellement avec new et perdant la DI.
#testing#interview

CSRF

NestJS 🟡 Mid

Cross-Site Request Forgery : attaque ou un site malveillant force le navigateur a envoyer des requetes authentifiees. Protege via des tokens anti-CSRF.

Comme quelqu'un qui forge ta signature pour signer un cheque a ta place sans que tu le saches.

import csurf from 'csurf';

app.use(csurf({ cookie: true }));
// Le token CSRF est envoye au client et verifie a chaque mutation

Cas d'usage : Proteger les applications avec sessions/cookies contre les requetes forgees.

Anti-pattern : Desactiver la protection CSRF sur les endpoints de mutation par facilite.
#security

Custom Decorator

NestJS 🟡 Mid

Decorateur personalise cree avec createParamDecorator ou applyDecorators pour extraire des donnees ou combiner des decorateurs existants.

Comme creer un raccourci clavier personnalise qui combine plusieurs actions en un seul geste.

export const CurrentUser = createParamDecorator(
  (data: unknown, ctx: ExecutionContext) => {
    const request = ctx.switchToHttp().getRequest();
    return request.user;
  },
);

Cas d'usage : Extraire l'utilisateur courant du token JWT dans chaque handler sans dupliquer le code.

Anti-pattern : Acceder a request.user directement partout au lieu de creer un decorateur reutilisable.
#core#interview

Custom Providers

NestJS 🟡 Mid

Providers definis avec useClass, useValue, useFactory ou useExisting pour un controle total sur ce qui est injecte. Permet l'injection de valeurs non-classes.

Comme choisir entre acheter un meuble en kit, le faire sur mesure ou recycler un ancien meuble.

providers: [
  { provide: 'API_KEY', useValue: process.env.API_KEY },
  { provide: Logger, useClass: ProdLogger },
  { provide: 'DB', useFactory: (cfg: ConfigService) =>
    createConnection(cfg.get('DB_URL')),
    inject: [ConfigService],
  },
]

Cas d'usage : Injecter des variables d'environnement, des connexions dynamiques ou des implementations alternatives.

Anti-pattern : Acceder directement a process.env dans les services au lieu d'injecter la configuration.
#core#interview

DataLoader

NestJS 🔴 Senior

Utilitaire qui regroupe et met en cache les requetes de base de donnees dans une execution GraphQL. Resout le probleme classique N+1.

Comme un livreur qui regroupe toutes les commandes d'un quartier en une seule tournee au lieu de faire un aller-retour par colis.

@Injectable({ scope: Scope.REQUEST })
export class UserLoader {
  private loader = new DataLoader<number, User>(async (ids) => {
    const users = await this.userService.findByIds([...ids]);
    return ids.map(id => users.find(u => u.id === id));
  });
  load(id: number) { return this.loader.load(id); }
}

Cas d'usage : Optimiser les resolvers GraphQL en batchant les requetes par entite pour eviter le N+1.

Anti-pattern : Charger les relations une par une dans chaque resolver sans DataLoader.
#communication#interview

Dependency Injection

NestJS 🟢 Junior

Pattern ou les dependances sont fournies a une classe par le framework plutot que creees par la classe elle-meme. NestJS utilise l'injection par constructeur.

Comme un restaurant ou les ingredients sont livres par les fournisseurs plutot que cultives par le chef.

@Injectable()
export class OrderService {
  constructor(
    private userService: UserService,
    private paymentService: PaymentService,
  ) {}
}

Cas d'usage : Decouple les classes pour faciliter les tests unitaires et permettre le remplacement des implementations.

Anti-pattern : Instancier les dependances avec new directement dans la classe au lieu de les injecter.
#core#interview#architecture

Dynamic Module

NestJS 🟡 Mid

Module configurable via une methode statique (forRoot/forRootAsync) qui retourne un DynamicModule. Permet de passer des options de configuration a l'import.

Comme un abonnement telephonique : le meme operateur mais tu choisis ton forfait (options) a la souscription.

@Module({})
export class MailModule {
  static forRoot(config: MailConfig): DynamicModule {
    return {
      module: MailModule,
      providers: [{ provide: 'MAIL_CONFIG', useValue: config }, MailService],
      exports: [MailService],
    };
  }
}

Cas d'usage : Creer des modules reutilisables comme les modules de config, cache ou mail avec des parametres variables.

Anti-pattern : Hardcoder la configuration directement dans le module au lieu de la rendre injectable.
#core#architecture#interview

E2E supertest

NestJS 🟡 Mid

Tests end-to-end qui simulent de vraies requetes HTTP via la librairie supertest. Testent le pipeline complet du request au response.

Comme un client mystere qui teste le restaurant de A a Z : de la reservation au dessert.

const app = moduleFixture.createNestApplication();
await app.init();

await request(app.getHttpServer())
  .post('/users')
  .send({ email: 'test@test.com', password: '12345678' })
  .expect(201)
  .expect(res => expect(res.body.email).toBe('test@test.com'));

Cas d'usage : Valider que les endpoints, la validation, les guards et la serialisation fonctionnent ensemble.

Anti-pattern : Ne tester que les services unitairement sans jamais verifier le pipeline HTTP complet.
#testing#interview

EventEmitterModule

NestJS 🟡 Mid

Module pour la communication asynchrone intra-application via evenements. Les services emettent des evenements et les listeners les traitent de facon decouple.

Comme un systeme de haut-parleurs dans un batiment : un message est diffuse et ceux concernes reagissent.

// Emission
this.eventEmitter.emit('order.created', new OrderCreatedEvent(order));

// Listener
@OnEvent('order.created')
async handleOrderCreated(event: OrderCreatedEvent) {
  await this.emailService.sendConfirmation(event.order);
}

Cas d'usage : Decoupler les effets de bord (email, notifications) de la logique metier principale.

Anti-pattern : Utiliser des appels directs entre services pour des side-effects au lieu d'evenements.
#core#architecture

Exception Filter

NestJS 🟡 Mid

Classe decoree @Catch qui intercepte les exceptions non gerees et les transforme en reponses HTTP structurees. Centralise la gestion d'erreurs.

Comme un filet de securite sous un trapeziste : il attrape les chutes et les transforme en atterrissage controle.

@Catch(HttpException)
export class HttpExceptionFilter implements ExceptionFilter {
  catch(exception: HttpException, host: ArgumentsHost) {
    const ctx = host.switchToHttp();
    const response = ctx.getResponse();
    response.status(exception.getStatus()).json({
      message: exception.message,
    });
  }
}

Cas d'usage : Formater toutes les erreurs API de maniere coherente avec des codes d'erreur et messages standardises.

Anti-pattern : Entourer chaque handler de try/catch au lieu d'utiliser un filtre d'exception global.
#core#interview

forwardRef

NestJS 🟡 Mid

Fonction utilitaire qui resout les dependances circulaires en retardant la resolution de la reference. Utilise un wrapper de fonction pour differer l'evaluation.

Comme dire 'je te presenterai mon collegue quand il arrivera' plutot que d'exiger sa presence immediate.

@Injectable()
export class CatService {
  constructor(
    @Inject(forwardRef(() => DogService))
    private dogService: DogService,
  ) {}
}

Cas d'usage : Resoudre les dependances circulaires entre deux services ou modules qui se referent mutuellement.

Anti-pattern : Utiliser forwardRef comme solution par defaut au lieu de repenser l'architecture pour eliminer les cycles.
#core#interview

Global Module

NestJS 🟢 Junior

Module decore avec @Global() dont les providers sont accessibles dans toute l'application sans import explicite. A utiliser avec parcimonie.

Comme le WiFi dans un hotel : disponible partout sans avoir a le demander a chaque etage.

@Global()
@Module({
  providers: [ConfigService],
  exports: [ConfigService],
})
export class ConfigModule {}

Cas d'usage : Exposer des services transversaux comme la configuration ou le logging sans imports repetitifs.

Anti-pattern : Rendre tous les modules globaux, ce qui detruit l'encapsulation et rend les dependances implicites.
#core#architecture

GraphQL @Subscription

NestJS 🔴 Senior

Decorateur pour definir des abonnements temps reel via WebSocket dans GraphQL. Permet au client de recevoir des mises a jour en push.

Comme un flux d'actualites en direct : tu t'abonnes une fois et les nouvelles arrivent automatiquement.

@Subscription(() => Comment, {
  filter: (payload, variables) =>
    payload.commentAdded.postId === variables.postId,
})
commentAdded(@Args('postId') postId: string) {
  return this.pubSub.asyncIterator('commentAdded');
}

Cas d'usage : Implementer des notifications temps reel comme les nouveaux commentaires ou messages.

#communication

GraphQL Resolver

NestJS 🟡 Mid

Classe decoree @Resolver qui definit les operations GraphQL (queries, mutations, subscriptions) en approche code-first avec des decorateurs TypeScript.

Comme un serveur de restaurant avec un menu a la carte : le client choisit exactement ce qu'il veut recevoir.

@Resolver(() => User)
export class UserResolver {
  constructor(private userService: UserService) {}

  @Query(() => [User])
  users() { return this.userService.findAll(); }

  @Mutation(() => User)
  createUser(@Args('input') input: CreateUserInput) {
    return this.userService.create(input);
  }
}

Cas d'usage : Exposer une API GraphQL code-first avec typage automatique du schema depuis TypeScript.

Anti-pattern : Mettre de la logique metier dans le resolver au lieu de la deleguer au service.
#communication#interview

gRPC

NestJS 🔴 Senior

Framework RPC haute performance utilisant Protocol Buffers et HTTP/2. NestJS supporte gRPC comme transport pour les microservices.

Comme un langage signe standardise entre machines : ultra-rapide et compact, mais moins lisible pour les humains.

@GrpcMethod('UserService', 'FindOne')
findOne(data: { id: number }): User {
  return this.userService.findOne(data.id);
}

// .proto: service UserService {
//   rpc FindOne (UserById) returns (User);
// }

Cas d'usage : Communiquer entre microservices avec des performances superieures a REST et un contrat strict.

Anti-pattern : Utiliser gRPC pour une API publique consommee par des navigateurs au lieu de REST/GraphQL.
#communication#architecture

Guard

NestJS 🟡 Mid

Classe @Injectable implementant CanActivate qui decide si une requete peut continuer. Ideal pour l'authentification et l'autorisation.

Comme un videur de boite de nuit : il verifie si tu as le droit d'entrer avant de te laisser passer.

@Injectable()
export class AuthGuard implements CanActivate {
  canActivate(context: ExecutionContext): boolean {
    const request = context.switchToHttp().getRequest();
    return !!request.headers.authorization;
  }
}

Cas d'usage : Proteger des routes avec authentification JWT, verifier les roles RBAC ou valider des permissions.

Anti-pattern : Verifier l'authentification dans chaque controller au lieu d'utiliser un guard reutilisable.
#core#security#interview

Helmet

NestJS 🟢 Junior

Middleware qui securise les headers HTTP (X-Frame-Options, CSP, HSTS, etc.). Protege contre les attaques web courantes comme le clickjacking.

Comme un casque de moto : protection basique mais indispensable contre les dangers les plus courants.

// main.ts
import helmet from 'helmet';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  app.use(helmet());
  await app.listen(3000);
}

Cas d'usage : Ajouter les headers de securite HTTP standard a toute API NestJS en production.

Anti-pattern : Deployer en production sans Helmet, laissant les headers de securite absents.
#security#interview

Hybrid Application

NestJS 🔴 Senior

Application NestJS qui combine un serveur HTTP et un ou plusieurs microservices dans le meme processus. Ecoute sur plusieurs transports simultanement.

Comme un restaurant avec salle et livraison : le meme service cuisine mais repond a deux canaux differents.

const app = await NestFactory.create(AppModule);
app.connectMicroservice({ transport: Transport.REDIS,
  options: { host: 'localhost', port: 6379 } });
await app.startAllMicroservices();
await app.listen(3000);

Cas d'usage : Migrer progressivement vers une architecture microservices en gardant l'API HTTP existante.

#architecture

Injection Scopes

NestJS 🔴 Senior

Definit le cycle de vie d'un provider : DEFAULT (singleton), REQUEST (par requete) ou TRANSIENT (nouvelle instance a chaque injection).

Comme un bureau : partage (singleton), un par client (request) ou jetable apres chaque usage (transient).

@Injectable({ scope: Scope.REQUEST })
export class RequestLogger {
  private requestId = randomUUID();
  log(msg: string) {
    console.log(`[${this.requestId}] ${msg}`);
  }
}

Cas d'usage : Utiliser REQUEST scope pour des services qui doivent stocker des donnees specifiques a chaque requete.

Anti-pattern : Utiliser REQUEST scope partout, ce qui desactive le singleton et degrade les performances.
#core#interview

Interceptor

NestJS 🟡 Mid

Classe implementant NestInterceptor qui enveloppe l'execution du handler via RxJS. Peut transformer la reponse, ajouter du logging ou gerer le cache.

Comme un emballeur cadeau : le produit (reponse) passe par lui avant et apres pour etre transforme.

@Injectable()
export class TransformInterceptor implements NestInterceptor {
  intercept(ctx: ExecutionContext, next: CallHandler) {
    return next.handle().pipe(
      map(data => ({ data, timestamp: Date.now() })),
    );
  }
}

Cas d'usage : Wrapper toutes les reponses dans un format standard, mesurer le temps de reponse ou implementer du cache.

Anti-pattern : Utiliser un interceptor pour de la validation de donnees au lieu d'un pipe.
#core#interview

IoC Container

NestJS 🟡 Mid

Le conteneur d'Inversion de Controle de NestJS qui gere la creation, la resolution et le cycle de vie de tous les providers enregistres.

Comme un annuaire professionnel : tu demandes un plombier et l'annuaire te fournit le bon contact.

// NestJS resout automatiquement le graphe de dependances
// UserController -> UserService -> UserRepository
// Il suffit de declarer les types dans le constructeur
@Injectable()
export class UserService {
  constructor(private repo: UserRepository) {}
}

Cas d'usage : Laisser le framework gerer la creation et l'injection de toutes les instances de l'application.

#core#architecture#interview

JWT Strategy

NestJS 🟡 Mid

Strategie Passport qui valide les tokens JWT extraits du header Authorization. Decode le payload et l'attache a request.user.

Comme un scanner de badge electronique : il lit le badge (token), verifie sa validite et identifie la personne.

@Injectable()
export class JwtStrategy extends PassportStrategy(Strategy) {
  constructor(config: ConfigService) {
    super({ jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
      secretOrKey: config.get('JWT_SECRET') });
  }
  validate(payload: any) { return { id: payload.sub, email: payload.email }; }
}

Cas d'usage : Proteger les endpoints API avec authentification stateless par token JWT.

Anti-pattern : Stocker des donnees sensibles (mot de passe, carte) dans le payload JWT.
#security#interview

Lifecycle Hooks

NestJS 🟡 Mid

Interfaces (OnModuleInit, OnModuleDestroy, OnApplicationBootstrap, OnApplicationShutdown) qui permettent d'executer du code a des moments cles du cycle de vie.

Comme les etapes d'ouverture et fermeture d'un magasin : mise en place le matin, rangement le soir.

@Injectable()
export class DbService implements OnModuleInit, OnModuleDestroy {
  async onModuleInit() {
    await this.connect();
  }
  async onModuleDestroy() {
    await this.disconnect();
  }
}

Cas d'usage : Initialiser des connexions base de donnees au demarrage et les fermer proprement a l'arret.

Anti-pattern : Initialiser des ressources dans le constructeur au lieu de onModuleInit, bloquant la DI.
#core#interview

Local Strategy

NestJS 🟡 Mid

Strategie Passport qui authentifie via email/mot de passe. Valide les credentials contre la base de donnees et retourne l'utilisateur.

Comme presenter sa carte d'identite et son mot de passe a un guichet pour prouver son identite.

@Injectable()
export class LocalStrategy extends PassportStrategy(Strategy) {
  constructor(private authService: AuthService) { super(); }
  async validate(username: string, password: string) {
    const user = await this.authService.validateUser(username, password);
    if (!user) throw new UnauthorizedException();
    return user;
  }
}

Cas d'usage : Implementer le login classique par email et mot de passe avant d'emettre un JWT.

Anti-pattern : Comparer les mots de passe en clair au lieu d'utiliser bcrypt.
#security#interview

MessagePattern vs EventPattern

NestJS 🔴 Senior

@MessagePattern attend une reponse (request-reply) tandis que @EventPattern est fire-and-forget (event-based). Deux paradigmes de communication inter-services.

Comme envoyer un recommande avec accuse de reception (message) vs jeter une bouteille a la mer (event).

// Request-reply: l'appelant attend une reponse
@MessagePattern('get_user')
getUser(data: { id: number }) {
  return this.userService.findOne(data.id);
}

// Fire-and-forget: pas de reponse attendue
@EventPattern('user_created')
handleUserCreated(data: UserCreatedEvent) {
  this.emailService.sendWelcome(data.email);
}

Cas d'usage : Utiliser MessagePattern pour les queries et EventPattern pour les notifications asynchrones.

Anti-pattern : Utiliser MessagePattern pour des events qui ne necessitent pas de reponse, bloquant inutilement.
#architecture#interview

Middleware

NestJS 🟡 Mid

Fonction ou classe executee avant le route handler, avec acces a request, response et next(). Compatible avec les middlewares Express/Fastify.

Comme un agent de securite a l'entree d'un immeuble : il verifie ton badge avant de te laisser monter.

@Injectable()
export class LoggerMiddleware implements NestMiddleware {
  use(req: Request, res: Response, next: NextFunction) {
    console.log(`${req.method} ${req.url}`);
    next();
  }
}

Cas d'usage : Logger les requetes, parser des headers custom ou modifier la requete avant qu'elle atteigne le controller.

Anti-pattern : Utiliser un middleware pour de la logique metier specifique a une route au lieu d'un interceptor ou guard.
#core#interview

Module

NestJS 🟢 Junior

Classe annotee @Module qui organise l'application en blocs fonctionnels cohesifs. Chaque module declare ses controllers, providers, imports et exports.

Comme un departement dans une entreprise : chaque departement a ses employes, ses outils et ses responsabilites bien definies.

@Module({
  imports: [DatabaseModule],
  controllers: [UserController],
  providers: [UserService],
  exports: [UserService],
})
export class UserModule {}

Cas d'usage : Structurer chaque domaine metier en module dedie pour maintenir la separation des responsabilites.

Anti-pattern : Mettre tous les providers dans AppModule au lieu de les repartir en modules fonctionnels.
#core#architecture#interview

Mongoose Model

NestJS 🟡 Mid

Interface pour interagir avec une collection MongoDB, injectee via @InjectModel. Fournit les methodes CRUD (find, create, updateOne, deleteMany).

Comme un guichet dedie a une collection : il sait lire, ecrire et supprimer les documents de sa collection.

@Injectable()
export class CatService {
  constructor(
    @InjectModel(Cat.name) private catModel: Model<Cat>,
  ) {}

  create(dto: CreateCatDto) {
    return new this.catModel(dto).save();
  }
}

Cas d'usage : Effectuer les operations CRUD sur les collections MongoDB dans un service NestJS.

#database

Mongoose Population

NestJS 🟡 Mid

Mecanisme pour charger automatiquement les documents references depuis d'autres collections. Equivalent des jointures SQL pour MongoDB.

Comme des liens hypertexte dans un document : cliquer dessus charge le contenu reference.

async findWithOwner(id: string) {
  return this.catModel
    .findById(id)
    .populate('owner')
    .exec();
}

Cas d'usage : Charger les documents lies sans faire plusieurs requetes manuelles.

Anti-pattern : Populer toutes les references par defaut, causant des requetes excessives sur les grandes collections.
#database

Mongoose Schema

NestJS 🟡 Mid

Definition de la structure d'un document MongoDB via @Schema et @Prop de @nestjs/mongoose. Genere le schema Mongoose a partir des decorateurs TypeScript.

Comme un formulaire avec des champs obligatoires et optionnels : il definit ce qu'un document doit contenir.

@Schema({ timestamps: true })
export class Cat {
  @Prop({ required: true })
  name: string;

  @Prop()
  age: number;

  @Prop({ type: Types.ObjectId, ref: 'Owner' })
  owner: Owner;
}

Cas d'usage : Definir la structure des documents MongoDB avec validation et typage TypeScript.

Anti-pattern : Stocker des documents sans schema defini, rendant les donnees incoherentes.
#database

OAuth2 Strategy

NestJS 🔴 Senior

Strategie Passport pour l'authentification via providers tiers (Google, GitHub, Facebook). Gere le flow d'autorisation OAuth2 avec callback.

Comme se connecter a un hotel avec sa carte de membre d'une chaine : un tiers de confiance confirme ton identite.

@Injectable()
export class GoogleStrategy extends PassportStrategy(Strategy, 'google') {
  constructor(cfg: ConfigService) {
    super({ clientID: cfg.get('GOOGLE_ID'),
      clientSecret: cfg.get('GOOGLE_SECRET'),
      callbackURL: '/auth/google/callback',
      scope: ['email', 'profile'] });
  }
  validate(token, refresh, profile) { return profile; }
}

Cas d'usage : Proposer le 'Login with Google/GitHub' pour simplifier l'onboarding utilisateur.

#security

Optional Dependencies

NestJS 🟡 Mid

Dependances marquees @Optional() qui ne causent pas d'erreur si elles ne sont pas enregistrees. Le provider recoit undefined si absent.

Comme commander un burger avec 'fromage en option' : si y'en a pas, tu recois quand meme ton burger.

@Injectable()
export class NotificationService {
  constructor(
    @Optional() @Inject('SMS_SERVICE')
    private sms?: SmsService,
  ) {}
}

Cas d'usage : Implementer des fonctionnalites optionnelles comme les notifications SMS qui ne sont pas toujours configurees.

#core

overrideGuard

NestJS 🟡 Mid

Methode du TestingModule pour remplacer un guard par une implementation permissive dans les tests. Permet de tester les handlers sans authentification.

Comme desactiver le badge d'acces pendant les tests incendie pour que tout le monde puisse circuler.

const module = await Test.createTestingModule({
  imports: [AppModule],
}).overrideGuard(AuthGuard)
  .useValue({ canActivate: () => true })
  .compile();

Cas d'usage : Tester les endpoints proteges sans avoir a generer de vrais tokens JWT.

#testing

overrideProvider

NestJS 🟡 Mid

Methode du TestingModule pour remplacer un provider par un mock ou une implementation alternative dans les tests.

Comme remplacer un acteur par sa doublure pour une scene dangereuse : le role est le meme, l'implementation change.

const module = await Test.createTestingModule({
  imports: [UserModule],
}).overrideProvider(UserService)
  .useValue({ findAll: jest.fn().mockResolvedValue([]) })
  .compile();

Cas d'usage : Mocker les services de base de donnees ou les APIs externes dans les tests d'integration.

#testing

Pagination

NestJS 🟡 Mid

Pattern pour retourner les resultats par pages via offset/limit ou cursor-based. Evite de charger des milliers d'enregistrements en une seule requete.

Comme un livre avec des pages : tu lis page par page au lieu de tout le livre d'un coup.

async findAll(page = 1, limit = 10) {
  const [items, total] = await this.repo.findAndCount({
    skip: (page - 1) * limit,
    take: limit,
  });
  return { items, total, page, lastPage: Math.ceil(total / limit) };
}

Cas d'usage : Toute API de liste doit etre paginee pour eviter les reponses massives et les timeouts.

Anti-pattern : Retourner tous les enregistrements sans pagination, causant des timeouts avec les grosses tables.
#core#interview

Passport

NestJS 🟡 Mid

Librairie d'authentification integree via @nestjs/passport. Fournit un systeme de strategies (JWT, Local, OAuth2) avec des guards dedies.

Comme un systeme de verification d'identite multi-documents : passeport, carte d'identite ou badge selon le contexte.

@Injectable()
export class JwtAuthGuard extends AuthGuard('jwt') {}

@Controller('profile')
export class ProfileController {
  @UseGuards(JwtAuthGuard)
  @Get()
  getProfile(@Request() req) { return req.user; }
}

Cas d'usage : Implementer l'authentification avec support multi-strategies dans une API NestJS.

Anti-pattern : Reimplementer la logique d'authentification from scratch au lieu d'utiliser Passport.
#security#interview

Pipe

NestJS 🟡 Mid

Classe implementant PipeTransform qui valide ou transforme les donnees entrantes avant qu'elles atteignent le handler. Fonctionne avec class-validator.

Comme un filtre a eau : l'eau (donnees) passe a travers et seule l'eau propre (valide) continue.

@Injectable()
export class ParseIntPipe implements PipeTransform {
  transform(value: string): number {
    const val = parseInt(value, 10);
    if (isNaN(val)) throw new BadRequestException('Not a number');
    return val;
  }
}

Cas d'usage : Valider les DTOs entrants avec class-validator ou transformer les parametres de route.

Anti-pattern : Valider manuellement les donnees dans le controller au lieu d'utiliser ValidationPipe avec des DTOs.
#core#interview

Prisma $transaction

NestJS 🔴 Senior

Methode de Prisma Client pour executer plusieurs operations en transaction atomique. Supporte le mode batch (tableau) et le mode interactif (callback).

Comme un contrat notarie : toutes les clauses s'appliquent ensemble ou le contrat est annule.

await this.prisma.$transaction(async (tx) => {
  const user = await tx.user.create({ data: userData });
  await tx.account.create({
    data: { userId: user.id, balance: 0 },
  });
});

Cas d'usage : Garantir l'atomicite lors de la creation d'entites liees comme user + compte.

#database

Prisma Client

NestJS 🟡 Mid

Client auto-genere et type-safe pour interagir avec la base de donnees. Fournit une API fluide avec autocompletion complete en TypeScript.

Comme un assistant personnel qui connait parfaitement ta base de donnees et te corrige en temps reel.

@Injectable()
export class UserService {
  constructor(private prisma: PrismaService) {}

  findAll() {
    return this.prisma.user.findMany({
      include: { posts: true },
    });
  }
}

Cas d'usage : Effectuer des requetes type-safe avec autocompletion et validation au compile-time.

Anti-pattern : Instancier PrismaClient dans chaque service au lieu de le wrapper dans un PrismaService singleton.
#database

Prisma Migration

NestJS 🟡 Mid

Systeme de migration genere automatiquement a partir des changements du schema Prisma. Cree des fichiers SQL versiones pour chaque modification.

Comme un photographe qui capture chaque modification de la maison pour pouvoir les rejouer ou annuler.

// Terminal
// npx prisma migrate dev --name add-user-role
// Genere: migrations/20240101_add_user_role/migration.sql
// ALTER TABLE "User" ADD COLUMN "role" TEXT DEFAULT 'user';

Cas d'usage : Versionner et deployer les changements de schema en production avec Prisma.

Anti-pattern : Utiliser prisma db push en production au lieu de prisma migrate deploy.
#database

Prisma Schema

NestJS 🟡 Mid

Fichier schema.prisma qui definit les modeles, relations et source de donnees en SDL (Schema Definition Language). Genere le client type-safe.

Comme un plan de construction : tu dessines la structure et Prisma genere toute la plomberie automatiquement.

// schema.prisma
model User {
  id    Int     @id @default(autoincrement())
  email String  @unique
  name  String?
  posts Post[]
}

model Post {
  id     Int  @id @default(autoincrement())
  author User @relation(fields: [authorId], references: [id])
  authorId Int
}

Cas d'usage : Definir le schema de donnees de facon declarative et generer un client ORM type-safe.

Anti-pattern : Modifier manuellement les fichiers generes par Prisma au lieu du schema.
#database

Provider

NestJS 🟢 Junior

Toute classe injectable dans le systeme DI de NestJS via @Injectable. Les services, repositories, factories et helpers sont tous des providers.

Comme un artisan dans une cooperative : il offre ses competences et peut etre appele par quiconque en a besoin.

@Injectable()
export class LoggerService {
  log(message: string) {
    console.log(`[LOG] ${message}`);
  }
}

Cas d'usage : Encapsuler la logique metier, l'acces aux donnees ou tout service reutilisable dans l'application.

Anti-pattern : Creer des providers sans @Injectable ou oublier de les declarer dans le tableau providers du module.
#core#interview

Rate Limiting

NestJS 🟡 Mid

Mecanisme qui limite le nombre de requetes par client dans une fenetre de temps. Implementable via @nestjs/throttler pour proteger contre les abus.

Comme un portillon de metro : il ne laisse passer qu'un certain nombre de personnes par minute.

@Module({
  imports: [ThrottlerModule.forRoot([{
    ttl: 60000,
    limit: 10,
  }])],
})
export class AppModule {}

@UseGuards(ThrottlerGuard)
@Controller('auth')
export class AuthController {}

Cas d'usage : Proteger les endpoints de login ou d'API publique contre le brute force et les abus.

Anti-pattern : Ne pas limiter les endpoints sensibles comme /login, permettant les attaques par force brute.
#security#interview

RBAC

NestJS 🟡 Mid

Role-Based Access Control : systeme d'autorisation ou les permissions sont attribuees a des roles (admin, user, editor) plutot qu'a des individus.

Comme les cles d'un immeuble : le gardien a le passe-partout, les residents ont la cle de leur etage.

@Injectable()
export class RolesGuard implements CanActivate {
  constructor(private reflector: Reflector) {}
  canActivate(ctx: ExecutionContext) {
    const roles = this.reflector.get<string[]>('roles', ctx.getHandler());
    if (!roles) return true;
    const user = ctx.switchToHttp().getRequest().user;
    return roles.includes(user.role);
  }
}

Cas d'usage : Restreindre l'acces aux endpoints admin ou moderateur selon le role de l'utilisateur.

Anti-pattern : Hardcoder les verifications de role dans chaque handler au lieu d'utiliser un guard + metadata.
#security#interview

REST/DTO

NestJS 🟢 Junior

Data Transfer Object : classe qui definit la structure des donnees entrantes/sortantes. Utilisee avec class-validator pour la validation automatique.

Comme un formulaire officiel : il definit les champs attendus et rejette les soumissions invalides.

export class CreateUserDto {
  @IsEmail()
  email: string;

  @IsString()
  @MinLength(8)
  password: string;

  @IsOptional()
  @IsString()
  name?: string;
}

Cas d'usage : Valider et typer les donnees entrantes de l'API avant qu'elles atteignent la logique metier.

Anti-pattern : Utiliser le type any ou l'entite base de donnees directement comme DTO d'entree.
#core#interview

ScheduleModule

NestJS 🟡 Mid

Module pour planifier des taches periodiques via des decorateurs cron (@Cron), interval (@Interval) ou timeout (@Timeout).

Comme un reveil programme : il execute automatiquement des actions a des heures definies.

@Injectable()
export class TaskService {
  @Cron('0 0 * * *') // Chaque jour a minuit
  async dailyCleanup() {
    await this.sessionService.deleteExpired();
  }

  @Interval(30000) // Toutes les 30 secondes
  checkHealth() { this.logger.log('Health check'); }
}

Cas d'usage : Executer des taches de maintenance comme le nettoyage de sessions expirees ou l'envoi de rapports.

Anti-pattern : Utiliser setInterval natif au lieu de @nestjs/schedule, perdant le contexte DI.
#core

Seeding

NestJS 🟡 Mid

Processus de remplissage de la base de donnees avec des donnees initiales ou de test. Execute via des scripts ou des modules dedies au demarrage.

Comme meubler un appartement temoin : tu prepares des donnees de demo pour que tout soit fonctionnel.

@Injectable()
export class SeedService implements OnModuleInit {
  constructor(private userService: UserService) {}

  async onModuleInit() {
    const count = await this.userService.count();
    if (count === 0) {
      await this.userService.create({ email: 'admin@app.com', role: 'admin' });
    }
  }
}

Cas d'usage : Initialiser les roles, permissions ou comptes admin lors du premier deploiement.

Anti-pattern : Seeder en production sans verifier si les donnees existent deja, causant des doublons.
#database

Serialization

NestJS 🟡 Mid

Transformation des objets en reponse JSON via ClassSerializerInterceptor et class-transformer. Permet d'exclure des champs sensibles avec @Exclude.

Comme un filtre photo qui masque les informations sensibles avant de publier.

export class UserEntity {
  id: number;
  email: string;

  @Exclude()
  password: string;

  constructor(partial: Partial<UserEntity>) {
    Object.assign(this, partial);
  }
}

Cas d'usage : Masquer les mots de passe, tokens internes et donnees sensibles des reponses API.

Anti-pattern : Retourner les entites brutes de la base de donnees sans filtrer les champs sensibles.
#core#security#interview

Service

NestJS 🟢 Junior

Provider dedie a la logique metier, annote @Injectable. Il encapsule les operations de domaine et est injecte dans les controllers ou autres services.

Comme le chef cuisinier d'un restaurant : le serveur (controller) prend la commande mais c'est le chef qui cuisine.

@Injectable()
export class UserService {
  constructor(private repo: UserRepository) {}

  async findAll(): Promise<User[]> {
    return this.repo.find();
  }
}

Cas d'usage : Centraliser la logique metier pour qu'elle soit testable independamment des controllers.

Anti-pattern : Acceder directement au repository depuis le controller en bypassant le service.
#core#interview

SSE

NestJS 🟡 Mid

Server-Sent Events : protocole HTTP unidirectionnel du serveur vers le client. Plus simple que WebSocket quand le flux est unidirectionnel.

Comme une radio : le serveur diffuse et les clients ecoutent, sans possibilite de repondre via le meme canal.

@Controller('events')
export class EventController {
  @Sse('stream')
  stream(): Observable<MessageEvent> {
    return interval(1000).pipe(
      map(i => ({ data: { count: i } } as MessageEvent)),
    );
  }
}

Cas d'usage : Streamer des mises a jour de progression, logs temps reel ou notifications sans WebSocket.

Anti-pattern : Utiliser WebSocket quand un flux unidirectionnel SSE suffit.
#communication

Swagger/OpenAPI

NestJS 🟡 Mid

Module @nestjs/swagger qui genere automatiquement la documentation API OpenAPI a partir des decorateurs, DTOs et controllers.

Comme un menu de restaurant genere automatiquement a partir des plats disponibles en cuisine.

const config = new DocumentBuilder()
  .setTitle('My API')
  .setVersion('1.0')
  .addBearerAuth()
  .build();
const doc = SwaggerModule.createDocument(app, config);
SwaggerModule.setup('api', app, doc);

Cas d'usage : Fournir une documentation API interactive et toujours a jour pour les developpeurs frontend.

Anti-pattern : Maintenir une documentation API manuelle qui se desynchronise du code.
#core#interview

TerminusModule

NestJS 🟡 Mid

Module de health checks via @nestjs/terminus. Expose un endpoint /health qui verifie la base de donnees, Redis, disque et services externes.

Comme un bilan de sante : le medecin verifie chaque organe et donne un bulletin de sante global.

@Controller('health')
export class HealthController {
  constructor(private health: HealthCheckService,
    private db: TypeOrmHealthIndicator) {}

  @Get()
  check() {
    return this.health.check([
      () => this.db.pingCheck('database'),
    ]);
  }
}

Cas d'usage : Fournir un endpoint de sante pour les load balancers et orchestrateurs comme Kubernetes.

Anti-pattern : Retourner toujours 200 sur /health sans verifier reellement l'etat des dependances.
#core

Transport Layer

NestJS 🔴 Senior

Couche d'abstraction de NestJS pour la communication entre microservices. Supporte TCP, Redis, NATS, MQTT, RabbitMQ, Kafka et gRPC.

Comme choisir entre la poste, le coursier ou le mail : le message est le meme, seul le moyen de transport change.

// main.ts
const app = await NestFactory.createMicroservice(AppModule, {
  transport: Transport.REDIS,
  options: { host: 'localhost', port: 6379 },
});
await app.listen();

Cas d'usage : Connecter des microservices NestJS via differents brokers de messages selon les besoins.

Anti-pattern : Coupler les services directement via HTTP au lieu d'utiliser un transport asynchrone.
#architecture

TypeORM Entity

NestJS 🟡 Mid

Classe decoree @Entity qui represente une table de base de donnees. Chaque propriete decoree (@Column, @PrimaryGeneratedColumn) correspond a une colonne.

Comme un plan d'architecte : il decrit la structure exacte de la table a construire.

@Entity()
export class User {
  @PrimaryGeneratedColumn()
  id: number;

  @Column({ unique: true })
  email: string;

  @Column({ default: true })
  isActive: boolean;
}

Cas d'usage : Definir le schema de la base de donnees directement dans le code TypeScript avec TypeORM.

Anti-pattern : Ajouter de la logique metier dans l'entite au lieu de la garder comme simple mapping.
#database#interview

TypeORM Migration

NestJS 🟡 Mid

Fichier versionne qui decrit les modifications de schema de base de donnees (up/down). Permet de gerer l'evolution du schema de facon reproductible.

Comme un historique Git mais pour la structure de ta base de donnees.

export class AddUserAge1234567890 implements MigrationInterface {
  async up(qr: QueryRunner) {
    await qr.addColumn('user',
      new TableColumn({ name: 'age', type: 'int', isNullable: true }));
  }
  async down(qr: QueryRunner) {
    await qr.dropColumn('user', 'age');
  }
}

Cas d'usage : Deployer des changements de schema en production de maniere securisee et reversible.

Anti-pattern : Utiliser synchronize: true en production au lieu de migrations versionees.
#database#interview

TypeORM QueryBuilder

NestJS 🔴 Senior

API fluide pour construire des requetes SQL complexes avec TypeORM. Supporte les jointures, sous-requetes, groupements et requetes paginee.

Comme assembler une requete en Lego : tu ajoutes chaque piece (clause) une par une pour construire la requete finale.

const users = await this.repo
  .createQueryBuilder('user')
  .leftJoinAndSelect('user.orders', 'order')
  .where('user.isActive = :active', { active: true })
  .orderBy('user.createdAt', 'DESC')
  .take(10)
  .getMany();

Cas d'usage : Construire des requetes complexes avec jointures, filtres dynamiques et pagination.

Anti-pattern : Concatener du SQL brut au lieu d'utiliser les parametres bindables, ouvrant la porte aux injections SQL.
#database#interview

TypeORM Relations

NestJS 🟡 Mid

Decorateurs (@OneToMany, @ManyToOne, @ManyToMany, @OneToOne) qui definissent les relations entre entites. Permettent le chargement eager ou lazy.

Comme les liens de parente dans un arbre genealogique : chaque relation a un type et une direction.

@Entity()
export class User {
  @OneToMany(() => Order, order => order.user)
  orders: Order[];
}

@Entity()
export class Order {
  @ManyToOne(() => User, user => user.orders)
  user: User;
}

Cas d'usage : Modeliser les associations entre tables et naviguer le graphe d'objets en TypeScript.

Anti-pattern : Charger les relations en eager par defaut, causant des requetes N+1 massives.
#database#interview

TypeORM Repository

NestJS 🟡 Mid

Pattern d'acces aux donnees qui fournit des methodes CRUD (find, save, delete) pour une entite. Injecte via @InjectRepository dans les services.

Comme un bibliothecaire specialise : il sait exactement comment chercher, ranger et preter les livres de sa section.

@Injectable()
export class UserService {
  constructor(
    @InjectRepository(User)
    private repo: Repository<User>,
  ) {}

  findAll() { return this.repo.find(); }
}

Cas d'usage : Effectuer les operations CRUD sur les entites sans ecrire de SQL brut.

Anti-pattern : Utiliser le repository directement dans le controller au lieu de passer par un service.
#database#interview

TypeORM Transactions

NestJS 🔴 Senior

Mecanisme pour executer plusieurs operations de base de donnees de facon atomique. Soit toutes reussissent, soit toutes sont annulees.

Comme un virement bancaire : le debit ET le credit doivent passer ensemble, sinon rien ne bouge.

async transfer(from: string, to: string, amount: number) {
  await this.dataSource.transaction(async (manager) => {
    await manager.decrement(Account, { id: from }, 'balance', amount);
    await manager.increment(Account, { id: to }, 'balance', amount);
  });
}

Cas d'usage : Garantir la coherence des donnees lors d'operations multi-tables comme les paiements.

Anti-pattern : Effectuer des operations liees sans transaction, risquant un etat incoherent en cas d'erreur.
#database#interview

Versioning

NestJS 🟡 Mid

Systeme de versioning d'API integre supportant URI (/v1/), header, media type et custom. Permet d'evoluer l'API sans casser les clients existants.

Comme les editions d'un livre : la v2 existe mais la v1 reste disponible pour ceux qui l'utilisent.

app.enableVersioning({ type: VersioningType.URI });

@Controller({ path: 'users', version: '1' })
export class UserV1Controller {}

@Controller({ path: 'users', version: '2' })
export class UserV2Controller {}

Cas d'usage : Maintenir la retrocompatibilite tout en deployant de nouvelles versions d'endpoints.

Anti-pattern : Modifier les endpoints existants sans versioning, cassant les clients en production.
#core

WebSocket Gateway

NestJS 🟡 Mid

Classe decoree @WebSocketGateway qui gere les connexions WebSocket bidirectionnelles. Utilise Socket.IO ou ws pour la communication temps reel.

Comme un talkie-walkie : la communication est instantanee dans les deux sens, sans besoin de 'rappeler'.

@WebSocketGateway({ cors: true })
export class ChatGateway {
  @WebSocketServer() server: Server;

  @SubscribeMessage('message')
  handleMessage(@MessageBody() data: string) {
    this.server.emit('message', data);
  }
}

Cas d'usage : Implementer un chat en temps reel, des notifications push ou un tableau de bord live.

Anti-pattern : Utiliser du polling HTTP pour des fonctionnalites temps reel au lieu de WebSocket.
#communication#interview

Autres stacks

Advanced Ecosystem Architecture CSS-in-JS DevOps HTML / CSS JavaScript MongoDB Mongoose Personalities PHP PostgreSQL React Sass Styled-Components Tailwind CSS Testing TypeScript WordPress
← Retour au lexique complet