Express
Express est le framework backend le plus utilisé pour NodeJS. Il facilite la construction d’applications structurées en microservices.
Installation
Exemple
app.js
Exécution
Ouvrir ensuite un navigateur à l’url http://localhost:3000
Les chemins d’accès / et /about fournissent une réponse http de type text/html ; le chemin /api fournit une réponse de type application/json (voir : Type du contenu de la réponse)
Avec l’écriture app.get('/about', ...), le path de l’url doit être exactement /about
Production de la réponse
Type du contenu de la réponse
L’appel response.send(val) envoie la réponse val dans response et ferme la connexion :
- si
valeststring, leContent-Typede la réponse est mis àtext/html - si
valestobjectouarray, leContent-Typede la réponse est mis àapplication/jsonetvalest stringifié - le
Content-Lengthde la réponse est affecté - le status de la réponse est mis à 200
responseest automatiquement fermée
status()
L’appel response.status(code) affecte le status de response à code et renvoie l’objet response modifié, pour chaînage. Exemple :
sendStatus()
sendFile()
Transfère le fichier path en assignant au header Content-Type de la requête, le mime-type associé à l’extension du fichier transféré
Exemple
Headers
Ajouter un header :
Envoyer un cookie au navigateur
L’instruction suivante ordonne au navigateur de stocker le cookie prefs avec la valeur video-games, books pour le domaine qui a servi la page :
Des options peuvent être ajoutées en troisième argument :
secure: true: le cookie n’est envoyé que sur des connexions HTTPShttpOnly: true: le cookie n’est pas accessible par javascriptsameSite=Strict: protects against CSRFexpires(Date) : date d’expiration du cookie. Si 0 ou non spécifié, créé un cookie de session, qui disparait à chaque fermeture du navigateur (mais pas à la fermeture d’un onglet)- ‘maxAge’ (Number) : analogue à
expires, durée relative à la date courante en millisecondes
Lors des requêtes ultérieures, le navigateur a l’obligation d’ajouter tous les cookies VALIDES stockés pour ce domaine, à toutes les requêtes à destination de ce domaine (même depuis un autre onglet).
Pour supprimer un cookie :
En réalité, le cookie n’est pas supprimé, mais sa date d’expiration est reportée dans le passé.
Extraction des query params
Ils sont directement accessibles sous forme d’un dictionnaire dans request.query
Test :
Utilisation d’un moteur de template : ejs
Express permet de plugger des moteurs de template de façon générique et de produire des pages avec la fonction render.
ejs est un de ces moteurs de template.
Installation
Example
Middlewares
Une application Express est essentiellement composée d’une suite ordonnée de middlewares.
Un middleware est une fonction de signature (request, response, next) qui peut :
- soit directement renvoyer la réponse si les conditions présentes dans
requestsont réunies ; l’envoi de la réponse est alors réalisé par un appel àresponse.send()ou un équivalent, et les middlewares suivants sont ignorés - soit ignorer totalement la requête par un appel à
next()sirequestne réunit pas les conditions voulues par le middleware - soit enrichir l’objet
requestavec de nouveaux attributs tout en passant la requête aux middlewares suivants par un appel ànext(). Par exemple un middleware d’authentification vérifiera querequestcontient des credentials valides pour un utilisateur, et il ajoutera un attributrequest.user.
Les middlewares sont ‘empilés’ dans un ordre précis selon les besoins de l’application :
app.use(<middleware>)
Exemple :
app.use(<route>, <middleware>)
- capture
<route>, mais aussi<route>/<id>, etc. - capture tous les verbes GET, POST, etc.
Middleware avec paramètres
Middlewares de parsing du body
Lorsque Express reçoit une requête HTTP (qui est un texte composé de lignes), il parse les principaux éléments de ce texte sous forme d’un objet javascript req. Par exemple req.method vaut ‘GET’ ou ‘POST’, req.query contient le dictionnaire des ‘query params’, etc. Le développeur peut alors écrire des middlewares qui exploitent les informations qui y sont contenues.
Par défaut, si la requête contient des données (un ‘body’/‘payload’, par exemple pour une requête POST ou PUT) ce body n’est pas intégré à req. La raison en est que ce body pourrait être très volumineux, et ce serait maladroit de l’intégrer systématiquement.
Un middleware de ‘parsing du body’ joue ce rôle : si une requête qui contient des données (un ‘body’/‘payload’) le traverse, il stocke ces données sous une forme adaptée dans req.body
Par exemple, lorsqu’une requête PATCH /api/users/98 + données JSON {a:1,b:2} traverse le middleware installé avec app.use(express.json()), ce middleware considère qu’il doit agir sur cette requête car req.headers['content-type'] a la valeur ‘application/json’. Il lit alors le texte des données “{a:1,b:2}”, le parse en un objet javascript { a:1, b: 2 }, et attache cette valeur à req.body.
A noter qu’un middleware de parsing du body ne renvoie pas de réponse : il se contente, lorsqu’il se déclenche, d’affecter une valeur à req.body, puis la requête passe au middleware suivant dans le pipeline des middlewares. C’est justement le but : les middleware qui suivent peuvent accéder à cette valeur et la traiter.
Il existe des ‘body-parser’ pour différents types de données :
Test :
Middleware de gestion des fichiers statiques à partir du système de fichiers du serveur
Une requête GET /aaa/bbb/ccc.x conduit à servir le fichier statique /var/www/html/myapp/aaa/bbb/ccc.x
Une requête GET /static/aaa/bbb/ccc.x conduit à servir le fichier statique /var/www/html/myapp/aaa/bbb/ccc.x
Sert les fichiers situés dans le sous-répertoire ‘assets’; GET /assets/logo.png servira le fichier ./assets/logo.png
Middleware d’ajout de headers CORS
Par défaut les API XMLHttpRequest et Fetch utilisées par les navigateurs interdisent les appels vers une destination différente de l’origine (nom de domaine ET numéro de port)
Pour les rendre possible, il faut ajouter des headers spécifiques ; c’est ce que fait le middleware ‘cors’
Middleware de parsing des cookies
Le middleware cookie-parser extrait les cookies non-expirés présents dans la requête et les met dans l’attribut req.cookies sous forme d’un dictionnaire (cookie_name, cookie_value)
Middleware de gestion des bearer tokens
Le token est attaché à l’attribut .token de la requête ; il est extrait des endroits suivants :
dans le header Authorization: Bearer <token>- clé
access_tokendansreq.body - clé
access_tokendansreq.query - (Optional) cookie avec la clé
access_token
ATTENTION : par réussi à l’utiliser avec un cookie, même après installation et usage de cookie-parser
Helmet
Ajoute des headers qui implémentent de bonnes pratiques de sécurité
