Créer sa première application Express

Tutoriel expliquant et montrant comment développer sa première application avec le framework Exress

NodeJS est un environnement bas niveau, tu as pu le voir dans mon article expliquant le fonctionnement de ce dernier et, si ce n’est pas encore fait, je t’invite à aller le voir dès maintenant (accéder à l’article).

Dès lors que l’on souhaite créer des applications plus ou moins complexes, on va rapidement se retrouver face à des problématiques de code pénibles et redontantes à gérer à cause de ce manque d’abstraction de la part de NodeJS.

Et c’est là qu’intervient l’utilisation d’un framework comme Express.

Express

Express est un micro-framework qui va nous permettre de créer des applications NodeJS beaucoup plus rapidement en ajoutant une couche d’abstraction, il va ainsi nous faciliter la création d’application NodeJS en nous évitant d’écrire certains morceaux de code.

Il est loin d’être aussi puissant qu’un Symfony mais il permettra par contre de créer rapidement des APIs ou des applications légères. Il va notamment simplifier la création de route et permettre d’utiliser des moteurs de template pour le renvoie de données.

Application Express – Tutos

Pour l’installer, on utilisera NPM au sein de notre projet:

npm install --save express

Pour bien comprendre la différence et l’abstraction que fait Express, nous allons recréer une application simple en NodeJS puis nous allons la convertir avec Express.

Commençons par la création du projet, n’oublies pas d’ouvrir ta console et de te positionner là où tu souhaites créer ton projet:

mkdir express-app
cd express-app
npm init -y
touch index.js
npm i --save express

On va maintenant implémenter une application NodeJS avec 2 routes différentes.

Il est nécessaire pour ça de modifier le fichier index.js:

const http = require('http'),
    url = require('url');

// Création du serveur
const server = http.createServer((req, res) => {

    // Récupération du chemin demandé par l'utilisateur
    const page = url.parse(req.url).pathname;

    // Paramètrage du statut et du type de renvoie
    res.writeHead(200, {'Content-Type': 'text/html'});

    let html = '<!DOCTYPE html>' +
        '<html class="h-100">' +
        '    <head>' +
        '        <meta charset="utf-8" />' +
        '        <title>Mon app Node.js !</title>' +
        '        <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-+0n0xVW2eSR5OomGNYDnhzAbDsOXxcvSN1TPprVMTNDbiYZCxYbOOl7+AMvyTG2x" crossOrigin="anonymous">' +
        '    </head>' +
        '    <body class="d-flex h-100 text-center text-white bg-dark">' +
        '     	<div class="cover-container d-flex w-100 h-100 p-3 mx-auto flex-column">' +
        '  <header class="mb-auto">' +
        '    <div>' +
        '      <h3 class="float-md-start mb-0">App NodeJS</h3>' +
        '    </div>' +
        '  </header>' +
        '  <main class="px-3">';


    if (page === '/') {
        html += '<h1>Hey ! Bienvenue :)</h1>';
    } else {
        html += '<h1>Page Introuvable</h1>';
    }

    html += '   </main>' +
        '       <footer class="mt-auto text-white-50">' +
        '           <p>Proposé par <a href="https://formationdeveloppeurweb.com/" class="text-white">Formation Développeur Web</a></p>' +
        '       </footer>' +
        '   </div>' +
        '   </body>' +
        '</html>';

    res.write(html);
    res.end();
});

server.listen(8080, () => {
    console.log('Le serveur est démarré sur le port 8080 !');
});

On peut voir que c’est rapidement difficile à lire et à maintenir.

Pour lancer le projet, il suffit de taper la commande suivante:

node .

Puis de se rendre sur l’url ⇒ http://localhost:8080/

En accédant à une autre url que celle donnée au-dessus, on tombera inévitablement sur la page possédant le titre ‘Page Introuvable’.

Il est maintenant temps d’utiliser Express !

Le framework va permettre de simplifier la création des routes mais aussi la création de du serveur.

On va notamment arrêter d’utiliser la fonction « createServer() » pour la remplacer par la simple fonction « express() ».

Prenons le même exemple écrit avec Express:

const express = require('express');

const app = express();

let headHtml = '<!DOCTYPE html>' +
    '<html class="h-100">' +
    '    <head>' +
    '        <meta charset="utf-8" />' +
    '        <title>Mon app Node.js !</title>' +
    '        <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-+0n0xVW2eSR5OomGNYDnhzAbDsOXxcvSN1TPprVMTNDbiYZCxYbOOl7+AMvyTG2x" crossOrigin="anonymous">' +
    '    </head>' +
    '    <body class="d-flex h-100 text-center text-white bg-dark">' +
    '     	<div class="cover-container d-flex w-100 h-100 p-3 mx-auto flex-column">' +
    '           <header class="mb-auto">' +
    '               <div>' +
    '                   <h3 class="float-md-start mb-0">App NodeJS</h3>' +
    '               </div>' +
    '           </header>' +
    '           <main class="px-3">';

let footerHTML = '           </main>' +
    '           <footer class="mt-auto text-white-50">' +
    '               <p>Proposé par <a href="https://formationdeveloppeurweb.com/" class="text-white">Formation Développeur Web</a></p>' +
    '           </footer>' +
    '       </div>' +
    '   </body>' +
    '</html>';

app.get('/', (req, res) => {
    res.send(headHtml + '<h1>Hey ! Bienvenue :)</h1>' + footerHTML);
});

// Cas par défaut si les autres urls n'ont pas matché
app.use((req, res) => {
    res.send(headHtml + '<h1>Page Introuvable</h1>' + footerHTML);
});

app.listen(8080, () => {
    console.log('Le serveur est démarré sur le port 8080 !');
});

Il est beaucoup plus simple de gérer les différentes routes. J’ai pris la décision ici de séparer le HTML en deux variables afin de le rentre un maximum réutilisable.

Dans une application plus complète, on pourra facilement exporter les routes dans un fichier de routing et on verra un peu plus loin dans cet article comment utiliser un moteur de template pour générer des vues.

Enfin, pour chaque route, il sera possible d’utiliser les 4 fonctions connues: post , put , patch , delete . Encore une fois, Express nous simplifiera la vie en ajoutant une certaine couche d’abstraction dans leur utilisation.

Route avec paramètres

Lorsqu’on crée une application, il arrive assez souvent de devoir faire passer un paramètre dans l’URL que l’utilisateur va requêter. Par exemple, l’identifiant d’une ressource spécifique dont on a besoin.

Comme dans la plupart des frameworks, la récupération et le passage de paramètres va être extrêmement simple.

Faisons passer dans notre première route 2 paramètres:

const express = require('express');

const app = express();

let headHtml = '<!DOCTYPE html>' +
    '<html class="h-100">' +
    '    <head>' +
    '        <meta charset="utf-8" />' +
    '        <title>Mon app Node.js !</title>' +
    '        <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-+0n0xVW2eSR5OomGNYDnhzAbDsOXxcvSN1TPprVMTNDbiYZCxYbOOl7+AMvyTG2x" crossOrigin="anonymous">' +
    '    </head>' +
    '    <body class="d-flex h-100 text-center text-white bg-dark">' +
    '     	<div class="cover-container d-flex w-100 h-100 p-3 mx-auto flex-column">' +
    '           <header class="mb-auto">' +
    '               <div>' +
    '                   <h3 class="float-md-start mb-0">App NodeJS</h3>' +
    '               </div>' +
    '           </header>' +
    '           <main class="px-3">';

let footerHTML = '           </main>' +
    '           <footer class="mt-auto text-white-50">' +
    '               <p>Proposé par <a href="https://formationdeveloppeurweb.com/" class="text-white">Formation Développeur Web</a></p>' +
    '           </footer>' +
    '       </div>' +
    '   </body>' +
    '</html>';

app.get('/:firstname?/:lastname?', (req, res) => {
    const firstname = req.params.firstname;
    const lastname = req.params.lastname;

    res.send(headHtml + `<h1>Hey ! Bienvenue ${firstname ? firstname : ''} ${lastname ? lastname : ''} :)</h1>` + footerHTML);
});

// Cas par défaut si les autres urls n'ont pas matché
app.use((req, res) => {
    res.send(headHtml + '<h1>Page Introuvable</h1>' + footerHTML);
});

app.listen(8080, () => {
    console.log('Le serveur est démarré sur le port 8080 !');
});

Ici, en utilisant le ? Juste après le paramètre, cela permet de prévenir la route que ce dernier est optionnel. Il ne reste donc qu’à vérifier s’il existe avant d’essayer de l’afficher.

Les paramètres sont récupérables au sein de la requête dans un objet nommé params . On pourra ensuite récupérer chaque paramètre par son nom donné dans la route.

Ainsi, les deux URLs d’exemple suivantes fonctionneront sans soucis:

EJS

Notre application fonctionne mais la génération et l’utilisation du HTML reste quand même assez pénible à utiliser.

On va donc utiliser un moteur de template pour simplifier tout ça.

J’ai choisi d’utiliser EJS dans cet article qui est assez simple à comprendre et à utiliser.

Il permet d’embarquer et d’interpréter du Javascript dans du HTML. Lorsque le moteur de template rendra le fichier, il fera en sorte de transformer les instructions Javascript en code HTML.

On retrouve dans EJS deux balises importantes:

  • <% %> ⇒ qui permet d’interpréter du Javascript sans afficher le résultat, on s’en servira pour des conditions ou des boucles par exemple
  • <%= %> ⇒ qui permet d’interpréter du Javascript et d’afficher le résultat, on s’en servira pour afficher le contenu de variables qu’on fera passer à la vue.

Dans un premier temps, il va être nécessaire d’expliquer à Express que l’application va utiliser un moteur de template. On va encore une fois obtenir quelque chose d’assez simple puisque tout est prévu au sein d’Express.

On commence par installer EJS:

npm install --save ejs

Puis juste après la création de l’application, on définit le moteur de template:

const express = require('express');

const app = express();

// Définition du moteur de rendu
app.set('view engine', 'ejs');

// Reste du code

Par défaut, Express cherchera les fichiers de vues dans un dossier nommé views à la racine du projet, il va donc falloir que l’on fasse ce dossier.

On en profitera pour créer par la même occasion deux vues:

  • index.ejs
  • not-found.ejs

Dans la vue index.ejs, on va devoir afficher les paramètres si ils sont disponibles. Voici le contenu final de notre vue:

<!DOCTYPE html>
<html class="h-100">
<head>
    <meta charset="utf-8"/>
    <title>Mon app Node.js !</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.1/dist/css/bootstrap.min.css" rel="stylesheet"
          integrity="sha384-+0n0xVW2eSR5OomGNYDnhzAbDsOXxcvSN1TPprVMTNDbiYZCxYbOOl7+AMvyTG2x" crossOrigin="anonymous">
</head>
<body class="d-flex h-100 text-center text-white bg-dark">
<div class="cover-container d-flex w-100 h-100 p-3 mx-auto flex-column">
    <header class="mb-auto">
        <div>
            <h3 class="float-md-start mb-0">App NodeJS</h3>
        </div>
    </header>
    <main class="px-3">
        <h1>Hey ! Bienvenue <%= firstname %> <%= lastname %> :)</h1>
    </main>
    <footer class="mt-auto text-white-50">
        <p>Proposé par <a href="https://formationdeveloppeurweb.com/" class="text-white">Formation Développeur Web</a>
        </p>
    </footer>
</div>
</body>
</html>

EJS est assez intelligent pour ne pas générer d’erreur s’il ne trouve la variable, il n’est donc pas nécessaire d’entourer l’affichage d’une condition.

Pour la page not-found.ejs, le contenu sera assez identique et simple:

<!DOCTYPE html>
<html class="h-100">
<head>
    <meta charset="utf-8"/>
    <title>Mon app Node.js !</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.1/dist/css/bootstrap.min.css" rel="stylesheet"
          integrity="sha384-+0n0xVW2eSR5OomGNYDnhzAbDsOXxcvSN1TPprVMTNDbiYZCxYbOOl7+AMvyTG2x" crossOrigin="anonymous">
</head>
<body class="d-flex h-100 text-center text-white bg-dark">
<div class="cover-container d-flex w-100 h-100 p-3 mx-auto flex-column">
    <header class="mb-auto">
        <div>
            <h3 class="float-md-start mb-0">App NodeJS</h3>
        </div>
    </header>
    <main class="px-3">
        <h1>Page Introuvable</h1>
    </main>
    <footer class="mt-auto text-white-50">
        <p>Proposé par <a href="https://formationdeveloppeurweb.com/" class="text-white">Formation Développeur Web</a>
        </p>
    </footer>
</div>
</body>
</html>

Il est maintenant temps de dire à Express de rentre ces vues lorsque c’est nécessaire.

On va donc modifier notre fichier server.js:

const express = require('express');

const app = express();

// Définition du moteur de rendu
app.set('view engine', 'ejs');

app.get('/:firstname?/:lastname?', (req, res) => {
    res.render('index', req.params); // Solution 1

    res.render('index', {
			firstname: req.params.firstname,
			lastname: req.params.lastname
		}); // Solution 2
});

// Cas par défaut si les autres urls n'ont pas matché
app.use((req, res) => {
    res.render('not-found', req.params);
});

app.listen(8080, () => {
    console.log('Le serveur est démarré sur le port 8080 !');
});

Pour notre route avec paramètres, j’ai mis 2 solutions, une très courte qui va renvoyer l’intégralité de l’objet paramètre à la vue et une deuxième plus longue qui renverra uniquement les informations que l’on souhaite.

Pour cette route, la solution 1 sera la plus pratique.

Conclusion

On s’arrête souvent à la création d’application ou de site internet avec NodeJS mais en réalité, son environnement bas niveau est une véritable force dans la création de script.

En effet, son spectre d’utilisation est beaucoup plus large qu’internet. On peut l’utiliser pour formater correctement des fichiers CSV, redimensionner des images, scrapper des informations sur un site internet et pleins d’autres choses.

Express, quant à lui, est un framework efficace dans la création d’application ou d’API basée sur NodeJS.

Pour aller plus loin, il serait intéressant de voir comment créer des vues partielles avec EJS ou encore comment découper son code en router et contrôleur afin de pouvoir faire grossir son projet sans soucis.

Si tout ceci t’intéresse, ma formation d’initiation sur Express mais aussi sur les Web Socket est disponible ! (accéder à ma formation)

Thomas C

Formateur sur des parcours DWWM & CDA, j'ai décidé d'aller plus loin en te partageant mes connaissances en vitesse supersonic 🚀 Prends ta revanche sur la vie !

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Formation Développeur Web