Voici une version en Markdown de votre guide sur NestJS :
Bonnes pratiques en développement avec NestJS (2026)
Contexte et enjeux
NestJS est une plateforme progressive pour la création d'applications aux événements côté serveur. Elle utilise un approche hybride, combinant les avantages du backend Node.js et le framework Angular. Cependant, avec une croissance rapide de l'écosystème NestJS, il devient crucial de suivre des bonnes pratiques pour assurer la qualité, la performance et la sécurité des applications.
Concepts clés
Architecture d'application
NestJS encourage une architecture modulaire basée sur les domaines métier. Voici un exemple typique :
// src/app.module.ts
import { Module } from '@nestjs/common';
import { UsersModule } from './users/users.module';
@Module({
imports: [UsersModule],
})
export class AppModule {}
Dépendances inversées (DI)
NestJS utilise le pattern Inversion of Control (IoC) avec Dependency Injection (DI). Cela permet une meilleure séparation des responsabilités et facilite la testabilité.
// src/users/users.service.ts
import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { User } from './user.entity';
@Injectable()
export class UsersService {
constructor(
@InjectRepository(User)
private readonly usersRepository: Repository<User>,
) {}
async findAll(): Promise<User[]> {
return this.usersRepository.find();
}
}
Contrôleurs
Les contrôleurs gèrent les requêtes HTTP et retournent des réponses. Ils sont associés aux routes.
// src/users/users.controller.ts
import { Controller, Get } from '@nestjs/common';
import { UsersService } from './users.service';
@Controller('users')
export class UsersController {
constructor(private readonly usersService: UsersService) {}
@Get()
async findAll() {
return this.usersService.findAll();
}
}
Entités et modèles de données
NestJS est souvent utilisé avec une base de données, et les entités décrivent la structure des tables.
// src/users/user.entity.ts
import { Entity, PrimaryGeneratedColumn, Column } from 'typeorm';
@Entity()
export class User {
@PrimaryGeneratedColumn()
id: number;
@Column()
name: string;
@Column()
email: string;
}
Sécurité
NestJS offre des fonctionnalités de sécurité intégrées :
// src/auth/jwt.strategy.ts
import { Injectable, UnauthorizedException } from '@nestjs/common';
import { PassportStrategy } from '@nestjs/passport';
import { ExtractJwt, Strategy } from 'passport-jwt';
@Injectable()
export class JwtStrategy extends PassportStrategy(Strategy) {
constructor() {
super({
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
ignoreExpiration: false,
secretOrKey: process.env.JWT_SECRET,
});
}
async validate(payload: any) {
if (!payload) {
throw new UnauthorizedException();
}
return { userId: payload.sub, username: payload.username };
}
}
Guide pratique pas à pas
1. Créer un nouveau projet NestJS
npx @nestjs/cli new my-project
2. Configurer les modules et contrôleurs
Créez un module et un contrôleur pour gérer l'authentification :
// src/auth/auth.module.ts
import { Module } from '@nestjs/common';
import { AuthService } from './auth.service';
import { AuthController } from './auth.controller';
@Module({
providers: [AuthService],
controllers: [AuthController],
})
export class AuthModule {}
3. Configurer la base de données
Ajoutez une configuration pour TypeORM :
// src/app.module.ts
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { UsersModule } from './users/users.module';
@Module({
imports: [
TypeOrmModule.forRoot({
type: 'postgres',
host: 'localhost',
port: 5432,
username: 'user',
password: 'password',
database: 'mydatabase',
entities: [__dirname + '/**/*.entity{.ts,.js}'],
synchronize: true, // À désactiver en production
}),
UsersModule,
],
})
export class AppModule {}
4. Implémenter les services
Créez un service pour gérer les utilisateurs :
// src/users/users.service.ts
import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { User } from './user.entity';
@Injectable()
export class UsersService {
constructor(
@InjectRepository(User)
private readonly usersRepository: Repository<User>,
) {}
async findAll(): Promise<User[]> {
return this.usersRepository.find();
}
}
5. Configurer le middleware et les filtres
NestJS permet de créer des middleware et des filtres pour gérer les erreurs :
// src/exception-filters/http-exception.filter.ts
import { ExceptionFilter, Catch, ArgumentsHost, HttpException } from '@nestjs/common';
import { Request, Response } from 'express';
@Catch(HttpException)
export class HttpExceptionFilter implements ExceptionFilter {
catch(exception: HttpException, host: ArgumentsHost) {
const ctx = host.switchToHttp();
const response = ctx.getResponse<Response>();
const request = ctx.getRequest<Request>();
const status = exception.getStatus();
response
.status(status)
.json({
statusCode: status,
timestamp: new Date().toISOString(),
path: request.url,
message: exception.message,
});
}
}
6. Configurer l'authentification JWT
Ajoutez le module d'authentification :
// src/auth/auth.module.ts
import { Module } from '@nestjs/common';
import { AuthService } from './auth.service';
import { AuthController } from './auth.controller';
import { JwtModule } from '@nestjs/jwt';
@Module({
imports: [JwtModule.register({ secret: 'secret' })],
providers: [AuthService],
controllers: [AuthController],
})
export class AuthModule {}
7. Configurer les routes protégées
Ajoutez une route protégée par JWT :
// src/users/users.controller.ts
import { Controller, Get } from '@nestjs/common';
import { UsersService } from './users.service';
import { UseGuards } from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';
@Controller('users')
export class UsersController {
constructor(private readonly usersService: UsersService) {}
@UseGuards(AuthGuard('jwt'))
@Get()
async findAll() {
return this.usersService.findAll();
}
}
Comparatif ou tableau recapitulatif
| Concept | Description |
|---|---|
| Architecture modulaire | Séparation des responsabilités selon les domaines métier. |
| DI (Dependency Injection) | Améliore la testabilité en séparant les dépendances. |
| Contrôleurs | Gèrent les requêtes HTTP et retournent des réponses. |
| Entités | Décrivent la structure des tables de base de données. |
| Sécurité | Fonctionnalités intégrées pour gérer l'authentification, la validation des entrées, etc. |
Retour d'expérience concret
En suivant ces bonnes pratiques, nous avons pu créer une application NestJS performante et sécurisée. Les modules modulaires ont permis une meilleure organisation du code, tandis que les services découplés facilitaient la maintenance et le test.
Nous avons également mis en place une authentification JWT pour protéger les routes sensibles de l'application. L'utilisation de la DI a grandement simplifié la gestion des dépendances et amélioré la testabilité du code.
En conclusion, NestJS est une plateforme très puissante pour le développement backend moderne. En suivant ces bonnes pratiques, nous pouvons créer des applications robustes, performantes et sécurisées.
Checklist ou plan d'action
- Créer un nouveau projet NestJS
- Configurer les modules et contrôleurs
- Configurer la base de données avec TypeORM
- Implémenter les services pour gérer les utilisateurs
- Configurer le middleware et les filtres pour les erreurs
- Configurer l'authentification JWT
- Configurer les routes protégées par JWT
En suivant ce plan d'action, vous serez bien équipé pour créer une application NestJS moderne et performante.