Express
Express est le framework serveur web le plus utilisé pour NodeJS. Il facilite la construction d’applications structurées en microservices.
Installation
$ npm install expressHello World
const express = require('express')
const app = express()
app.get('/foo', function (request, response) {
response.send('Hello Foo!')
})
app.get('/bar', function (request, response) {
response.send('Hello Bar!')
})
app.listen(3000, function () {
console.log("Server listening on port 3000")
})
Production de la réponse
Contenu
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 :
response.status(500).send('Erreur inconnue')
sendStatus()
res.sendStatus(200) // equivalent to res.status(200).send('OK')
res.sendStatus(403) // equivalent to res.status(403).send('Forbidden')
res.sendStatus(404) // equivalent to res.status(404).send('Not Found')
res.sendStatus(500) // equivalent to res.status(500).send('Internal Server Error')
sendFile()
res.sendFile(path)
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é
Headers
Ajouter un header :
res.set('Content-Type', 'application/json')
res.set('Cache-Control', 'max-age=3600, must-revalidate')
Envoyer un cookie au navigateur
res.cookie(<name>, <value>[, <options>])
ex :
res.cookie('prefs', 'video-games,books')
Les cookies sont ensuite ajoutés à chaque requête ultérieure du navigateur.
Extraction des query params
Ils sont directement accessibles sous forme d’un dictionnaire dans request.query
const express = require('express')
const app = express()
app.get('/api/pages', function (request, response) {
let queryParams = request.query
console.log('queryParams', queryParams)
//...
response.send(...)
})
const port = process.env.PORT || 3000
app.listen(port, function () {
console.log(`app listening on port ${port}`)
})
Test :
$ curl http://localhost:3000/api/pages?a=1&b=azer
Activité à réaliser
Recréer yesno.wtf et son webservice /api
Middlewares
Une application express est une succession ordonnée d’appels de fonctions middleware, qui transforment progressivement response à partir de request :
- middlewares d’application
- middlewares de routage
- middleware de traitement d’erreurs
- etc.
app.use(<middleware>)
Exemple :
let logger = (req, res, next) => {
console.log('request', req)
next()
}
app.use(logger)
app.use(<route>, <middleware>)
Exemple : app.use('/api/users', middlewareFunction)
- capture
/api/users, mais aussi/api/users/<id>, etc. - capture tous les verbes GET, POST, etc.
Exemple : app.use('/api/users/:id', middlewareFunction)
- l’argument
idest accessible dansrequest.params.id
Middleware avec paramètres
let middleware = (param1, param2) => (req, res, next) => {
...
}
app.use(middleware(p1, p2))
Middlewares de parsing du body
express.json() etc. ajoutent un attribut body à request contenant le contenu parsé du corps (body) de la requête, en fonction du Content-Type spécifié dans les headers
// Content-Type: application/x-www-form-urlencoded
app.use(express.urlencoded({ extended: true }))
// Content-Type: application/json
app.use(express.json())
// Content-Type: html/text
app.use(express.text())
Test :
$ curl -X POST -d "azer" -H "Content-Type: text/plain" http://localhost:3000/api/pages?path=/my/page
Middleware de gestion des fichiers statiques à partir du système de fichiers du serveur
const express = require('express')
const app = express()
app.use(express.static('/var/www/html/myapp'))
app.listen(3000, () => console.log('running'))
Une requête /aaa/bbb/ccc.x conduit à servir le fichier statique /var/www/html/myapp/aaa/bbb/ccc.x
app.use('/static', express.static('/var/www/html/myapp'))
Une requête /static/aaa/bbb/ccc.x conduit à servir le fichier statique /var/www/html/myapp/aaa/bbb/ccc.x
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’
// allows CORS requests for all origins
app.use(cors())
Middleware de gestion des cookies
Le middleware cookie-parser extrait les cookies présents dans la requête et les met dans l’attribut req.cookies sous forme d’un dictionnaire (cookie_name, cookie_value)
app.use(cookie-parser())
Middleware de gestion des bearer tokens
const bearerToken = require('express-bearer-token')
...
app.use(bearerToken())
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
Helmet
Ajoute des headers qui implémentent de bonnes pratiques de sécurité
app.use(helmet())
Activité à réaliser
Implémenter un point d’accès REST /api/users (sauvegardé dans un dictionnaire local)
