Retour aux articles

Créer un serveur API avec NestJS : le guide ultime

Formation NestJS 2024
7 minutes de lecture- 203 vues

Quand j'ai commencé à développer des serveurs API en NodeJS, j'avais beaucoup de mal à utiliser Express. J'étais débutant, et je ne connaissais pas encore tous les concepts de développeur : réutiliser du code, fonctions asynchrones et Typescript.

Je voulais voir comment les pros faisaient. Je voulais lire du code propre et bien organisé. Je ne voulais surtout pas coder toutes mes routes dans le même fichier !

Puis j'ai découvert NestJS. Son générateur de projet m'a été d'une grande aide. Je pouvais, grâce à son outil CLI générer une base de code en Typescript avec Express déjà configuré. Il y avait des exemples de routes, un contrôleur, un service et un module.

En plus, la documentation était très concise. Ça m'a plu.

Pourquoi utiliser NestJS comme serveur API ?Header Icon

J'avais un besoin spécifique : Créer une base de données pour sauvegarder des données. Récupérer ces données côté client et les afficher. Et pouvoir les modifier (toujours côté client).

NestJS a répondu à ce besoin rapidement. Donc je l'ai choisi.

Je recommande ce framework aux développeurs qui veulent créer un serveur API en Javascript. Mais je ne le recommande pas parce qu'il est mieux que les autres (il l'est 😉).

Je le recommande, car il est dogmatique : il impose une structure de code. Il nous force à réfléchir à la manière dont on va organiser notre code. Pour un développeur débutant, c'est un excellent moyen d'apprendre à coder proprement.

Pré-requisHeader Icon

Assure-toi d'avoir Node et NPM installés sur votre machine. Des connaissances en Javascript et Git sont recommandées. Nous allons aussi beaucoup utiliser le terminal de commande.

Ce que tu vas apprendre et construireHeader Icon

  • Les bases de NestJS (routes, contrôleurs, services, modules)
  • Utiliser l'ORM Prisma pour gérer la base de données
  • Créer quelques comptes utilisateurs (connexion et inscription par email / mot de passe)
  • Envoyer des alertes par email (nouveau compte, mot de passe oublié) avec Courier
  • Ajouter l'authentification avec JWT pour les identifier
  • FRONTEND : Instantier un projet React avec Remix
  • Créer un formulaire d'inscription et de connexion
  • Connecter le frontend et le backend
  • Créer un chat en temps réel avec Socket.io (implémentation backend)
  • Implémenter le chat côté frontend
  • Héberger le code source sur Github (backend et frontend)
  • DÉPLOIEMENT : Commander un serveur d'hébergement (VPS) sur Amazon Lightsail
  • Configurer le nom de domaine avec Amazon Route 53
  • Configurer Caddy sur le serveur
  • Créer le fichier Docker pour le serveur (et le frontend)
  • Configurer les Github Actions pour héberger notre code source à chaque commit
  • Ajouter les variables d'environnement au repository Github
  • Tester l'application en production
  • FEATURE : Ajouter la logique d'upload des images
  • Héberger les images sur AWS S3
  • FEATURE : Ajouter la logique de paiement avec Stripe
  • Paramétrer et écouter les websockets de Stripe pour recevoir les évènements de paiement

Stack techniqueHeader Icon

Voici la stack que j'utilise au quotidien :

Côté serveur (backend)Header Icon

  • Framework NestJS
  • librairie Fastify comme serveur HTTP. Pareil qu'Express, mais 2x plus rapide.
  • Prisma ORM pour définir le modèle de nos données
  • base de donnée MySQL hébergée sur Planetscale
  • Socket.io pour envoyer les messages en temps réel (websockets)
  • Stripe pour envoyer de l'argent
  • Courier / Resend pour envoyer les emails (compte créé, mot de passe oublié, nouveau message reçu ...)
  • AWS S3 pour héberger les images
  • Passport pour gérer l'authentification en créant un token sécurisé JWT
  • Zod pour valider les données
  • et bien d'autres ...

Côté client (frontend)Header Icon

DéploiementHeader Icon

  • Amazon Route 53 pour le nom de domaine
  • Amazon Lightsail pour le serveur d'hébergement (VPS)
  • Github Actions pour déployer automatiquement notre code
  • Docker pour exécuter notre code dans un environnement virtualisé
  • Caddy pour gérer les certificats SSL

Formation vidéoHeader Icon

Tu peux également suivre ce guide au format vidéo.

Créer ton premier serveur API avec NestJS (Authentification par JWT)Header Icon

Développe ta MESSAGERIE en TEMPS RÉEL avec Socket.ioHeader Icon

Héberge tes IMAGES sur AWS S3 en JavascriptHeader Icon

Gère des PAIEMENTS en JAVASCRIPT avec STRIPE.JSHeader Icon

Installation du projetHeader Icon

Maintenant c'est à toi de jouer !

Pour créer ta super API, tu dois d'abord installer l'outil CLI.

Terminal

_10
npm i -g @nestjs/cli

Tu vas maintenant créer le dossier du projet. Il sera généré dans le dossier où tu exécutes la commande terminal. (Tu peux entrer pwd pour voir le chemin de ton dossier actuel)

Terminal

_10
nest new nestjs-superchat # Remplacez "nestjs-superchat" par le nom de votre choix

Génération d'un nouveau projet NestJS

Architecture du projetHeader Icon

Avec NestJS, la bonne pratique est de nommer les fichiers en fonction de leur type.

Voici les 4 principaux types de fichiers :

Le serviceHeader Icon

Toute la logique de notre application se trouve dans les services. Modification des données, envoi d'emails, authentification ... Ces fichiers contiennent le plus de lignes de code. Si tu fais un CRUD, tu écriras toute la logique dans un service.

Voici le service de base :

app.service.ts

_10
import { Injectable } from '@nestjs/common';
_10
_10
@Injectable()
_10
export class AppService {
_10
getHello(): string {
_10
return 'Hello World!';
_10
}
_10
}

Notez le décorateur @Injectable(). NestJS utilise le concept d'Injection de Dépendances. Ce décorateur signifie que ce service peut être injecté (et utilisé) dans un autre service.

Pour utiliser la méthode getHello() , tu vas devoir injecter le service AppService à l'intérieur d'un autre service. Tu ne pourras pas "importer" directement la méthode.

Je t'en parle plus en détail juste en dessous.

Le contrôleurHeader Icon

Les contrôleur permettent de définir les routes. Une route est accessible via une URL.

Voici un exemple de contrôleur (j'ai rajouté une route /posts) qui est accessible via l'URL http://localhost:3000/posts

app.controller.ts

_17
import { Controller, Get } from '@nestjs/common';
_17
import { AppService } from './app.service';
_17
_17
@Controller()
_17
export class AppController {
_17
constructor(private readonly appService: AppService) {}
_17
_17
@Get()
_17
getHello(): string {
_17
return this.appService.getHello();
_17
}
_17
_17
@Get('/posts')
_17
getPosts(): string {
_17
return this.appService.getHello();
_17
}
_17
}

Après la déclaration de l'AppController, tu vois une fonction constructor. Elle permet d'injecter le service AppService dans le contrôleur. C'est l'Injection de Dépendance. Pour utiliser AppService, tu l'injectes dans le constructeur. Si tu utilises TypeScript, la syntaxe paraît familière.

La méthode constructor() sera exécutée à l'initialisation du fichier. Dans cet exemple, elle contient un paramètre private readonly appService: AppService.

Le mot-clé private rend la variable inaccessible de l'extérieur (les fichiers important AppController n'y auront pas accès). Le mot-clé readonly rend la variable non modifiable. (Au cas où tu modifies la valeur de appService par erreur).

Tu accèdes aux méthodes public de AppService via this.appService.

Le ModuleHeader Icon

Le module est le fichier le plus important. Il permet de définir les contrôleurs, les services et potentiellement d'autres modules.

Voici un exemple de module :

app.module.ts

_10
import { Module } from '@nestjs/common';
_10
import { AppController } from './app.controller';
_10
import { AppService } from './app.service';
_10
_10
@Module({
_10
imports: [],
_10
controllers: [AppController],
_10
providers: [AppService],
_10
})
_10
export class AppModule {}

Pour que la route déclarée dans AppController soit accessible, tu as besoin d'importer ton fichier contrôleur dans le module.

Le décorateur @Module permet de définir les contrôleurs, les services et les modules importés.

Par exemple, notre module d'Authentification aura besoin du module JWT pour générer des tokens sécurisés.

auth.module.ts

_16
import { Module } from '@nestjs/common';
_16
import { JwtModule } from '@nestjs/jwt';
_16
import { JwtStrategy } from './jwt.strategy';
_16
_16
@Module({
_16
imports: [
_16
JwtModule.register({
_16
secret: process.env.JWT_SECRET,
_16
signOptions: {
_16
expiresIn: '30d',
_16
},
_16
}),
_16
],
_16
providers: [JwtStrategy],
_16
})
_16
export class AuthModule {}

Articles similaires

Rejoins la

newsletter