Nouveau : Datasets open source gratuits disponibles !Decouvrir →
🟢
Intermediaire 25 min NestJS

Migrer de Express vers NestJS

Pourquoi Migrer de Express vers NestJS ?

La transition de Express à NestJS peut offrir plusieurs avantages aux développeurs qui cherchent à créer des applications robustes, maintenables et modulaires. En effet, NestJS est une plateforme basée sur le design de modèles Microservices, ce qui lui permet d'offrir un architecture plus propre et scalable. Plus précisément, NestJS est construit sur les dernières technologies du langage TypeScript, ce qui offre des avantages en termes de type-checking et de développement assuré.

Un cas concret pour migrer de Express vers NestJS pourrait être le développement d'une application backend complexe avec une architecture Microservices. Dans ce cas, NestJS permet de créer facilement ces services et d'interconnecter entre eux, tout en offrant des fonctionnalités comme les injections de dépendances, les tests unitaires faciles à mettre en place et la gestion efficace des erreurs.

Prerequis

  • Connaissance approfondie de Node.js et Express
  • Familiarité avec TypeScript
  • Compréhension du concept d'architecture Microservices
  • Installation de Node.js (v14.x ou plus tard)
  • Installation de npm (Node Package Manager)

Concepts fondamentaux

Architecture Microservices

NestJS est conçu pour être une plateforme pour développer des applications basées sur le design de modèles Microservices. Les microservices sont des services autonomes qui communiquent entre eux via des APIs REST ou gRPC. Chaque service peut être développé, déployé et échelle indépendamment.

// Structure d'un microservice NestJS
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';

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

Injections de Dépendances

L'injection de dépendances est un pattern qui permet d'injecter des objets nécessaires dans les classes. Cela rend le code plus modulaire et facile à tester.

// Exemple d'injection de dépendances
import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { User } from './user.entity';

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

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

Middleware

Middleware est une fonction qui a accès à l'objet de requête (req), à l'objet de réponse (res) et à la chaîne suivante dans le cycle de traitement des requêtes. Elle peut effectuer des tâches telles que la validation des données, la gestion des erreurs ou la journalisation.

// Exemple d'un middleware personnalisé
import { Injectable, NestMiddleware } from '@nestjs/common';
import { Request, Response, NextFunction } from 'express';

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

DTO (Data Transfer Object)

Les DTO sont des objets utilisés pour transférer des données entre les différents composants de l'application. Ils permettent de spécifier la structure des données et de valider ces données avant leur utilisation.

// Exemple d'un DTO
import { IsNotEmpty, IsEmail } from 'class-validator';

export class CreateUserDto {
  @IsNotEmpty()
  username: string;

  @IsNotEmpty()
  @IsEmail()
  email: string;
}

Mise en pratique : projet fil rouge

Nous allons créer un gestionnaire de tâches basé sur NestJS. Le projet comprendra les fonctionnalités suivantes :

  1. Création d'une tâche
  2. Récupération de toutes les tâches
  3. Suppression d'une tâche

Étape 1 : Initialisation du Projet

Commencez par créer un nouveau projet NestJS.

npm install -g @nestjs/cli
nest new task-manager
cd task-manager

Étape 2 : Création des entités et modèles

Créez une entité Task pour représenter les tâches dans la base de données.

// src/task/entities/task.entity.ts
import { Entity, PrimaryGeneratedColumn, Column } from 'typeorm';

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

  @Column({ type: 'varchar', length: 255 })
  title: string;

  @Column({ type: 'text' })
  description: string;

  @Column({ type: 'boolean', default: false })
  isCompleted: boolean;
}

Créez un modèle TaskService pour gérer les opérations CRUD sur les tâches.

// src/task/task.service.ts
import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { Task } from './entities/task.entity';

@Injectable()
export class TaskService {
  constructor(
    @InjectRepository(Task)
    private readonly taskRepository: Repository<Task>,
  ) {}

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

  async create(taskDto: Task): Promise<Task> {
    const newTask = this.taskRepository.create(taskDto);
    return this.taskRepository.save(newTask);
  }

  async delete(id: number): Promise<void> {
    await this.taskRepository.delete(id);
  }
}

Étape 3 : Création des contrôleurs

Créez un contrôleur TaskController pour gérer les requêtes HTTP.

// src/task/task.controller.ts
import { Controller, Get, Post, Body, Param } from '@nestjs/common';
import { TaskService } from './task.service';
import { CreateTaskDto } from './dto/create-task.dto';

@Controller('tasks')
export class TaskController {
  constructor(private readonly taskService: TaskService) {}

  @Post()
  async create(@Body() createTaskDto: CreateTaskDto): Promise<Task> {
    return this.taskService.create(createTaskDto);
  }

  @Get()
  async findAll(): Promise<Task[]> {
    return this.taskService.findAll();
  }

  @Delete(':id')
  async delete(@Param('id') id: number): Promise<void> {
    await this.taskService.delete(id);
  }
}

Étape 4 : Configuration des routes

Ajoutez les routes dans app.module.ts pour lier le contrôleur aux routes HTTP.

// src/app.module.ts
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { TaskController } from './task/task.controller';
import { TaskService } from './task/task.service';
import { Task } from './task/entities/task.entity';

@Module({
  imports: [
    TypeOrmModule.forRoot({
      type: 'sqlite',
      database: 'tasks.db',
      entities: [Task],
      synchronize: true,
    }),
    TypeOrmModule.forFeature([Task]),
  ],
  controllers: [TaskController],
  providers: [TaskService],
})
export class AppModule {}

Étape 5 : Exécution du projet

Exécutez le projet et testez les routes.

npm run start:dev

Allez sur http://localhost:3000/tasks pour voir les tâches, http://localhost:3000/tasks pour créer une nouvelle tâche et http://localhost:3000/tasks/:id pour supprimer une tâche.

Erreurs frequentes et debugging

  1. Erreur : "Cannot find module 'typeorm'"

    // code_incorrect = import { Repository } from 'typeorm';
    

    Correction :

    // code_correct = import { Repository } from 'typeorm';
    npm install typeorm reflect-metadata --save
    npm install @nestjs/typeorm --save
    
  2. **Erreur : "Type 'CreateTaskDto' is not assignable to type 'Partial'"

    // code_incorrect = return this.taskService.create(createTaskDto);
    

    Correction :

    // code_correct = const newTask = this.taskRepository.create(createTaskDto);
    // return this.taskRepository.save(newTask);
    
  3. **Erreur : "Cannot find name 'Promise'"

    // code_incorrect = async findAll(): Promise<Task[]> {
    

    Correction :

    // code_correct = async findAll(): Promise<Task[]> {
    

Pour aller plus loin

  1. Documentation NestJS officielle : https://docs.nestjs.com/
  2. TypeORM pour la gestion des bases de données : https://typeorm.io/
  3. Présentation des Microservices avec NestJS : https://nestjs.io/microservices/

Défi pratique

Créez un application API de blog simple avec les fonctionnalités suivantes :

  1. Création d'un article
  2. Récupération de tous les articles
  3. Suppression d'un article

Utilisez NestJS pour développer l'API et TypeORM pour la gestion de la base de données SQLite.

Besoin d'aide sur NestJS ?

Besoin d'aide sur un projet technique ? Decrivez-le pour des conseils personnalises.

Recevoir des conseils

Questions frequentes

Quelle est la différence principale entre Express et NestJS ?
Express est un framework minimaliste pour Node.js, tandis que NestJS est un framework complet basé sur TypeScript qui utilise le design pattern de l'architecture microservices.
Comment migrer une application Express existante vers NestJS ?
Pour migrer une application Express, vous devrez commencer par créer un nouveau projet NestJS. Ensuite, refactoring du code pour utiliser les controllers et services de NestJS au lieu des routes d'Express.
Est-il possible de conserver la base de code Express tout en ajoutant des fonctionnalités NestJS ?
Oui, il est possible. Vous pouvez intégrer votre application Express existante avec une nouvelle couche NestJS qui s'occupe du traitement métier et de la communication avec d'autres services.

Pages liees

Chaque semaine, le meilleur de la tech francaise

Tendances, salaires, outils et opportunites — directement dans votre boite mail.

Gratuit. Desabonnement en un clic. Pas de spam.