title | layout |
---|---|
Partie 3 - Utilisation du système de fichiers |
default |
- Lire et modifier des fichiers avec Node.js.
- Définir des fonctions asynchrones.
- Application: améliorer notre chat-bot de la partie 1.
Prérequis:
- savoir appeler des fonctions asynchrones à l'aide de callback,
Promise
etasync
+await
. - savoir créer et tester des routes d'API HTTP GET et POST avec Node.js et Express.js.
- savoir exécuter un programme Node.js depuis un shell, à l'aide de la commande
node
. (car les sites "repl.it" et "glitch.com" ne donnent pas accès au système de fichiers)
Durée estimée: 4 heures.
L'utilisation de fonctions d'entrées-sorties synchrones (comme readFileSync() et writeFileSync(), par exemple) est à proscrire dans les programmes Node.js, et particulièrement dans l'implémentation de serveurs. (comme notre chat-bot)
En effet, ces opérations sont asynchrones par nature, car leur temps d'exécution est imprévisible. Or, exécuter ce genre d'opérations de manière synchrone revient à bloquer l'exécution du programme Node.js en attendant que celles-ci soient terminées.
Un serveur web doit être en permanence capable de recevoir des requêtes, et d'y répondre au plus vite. Afin de permettre cela, nous allons devoir effectuer nos opérations d'entrées-sorties de manière asynchrone, au lieu de synchrone.
Pour nous familiariser avec les fonctions de lecture et d'écriture de fichiers fournies par Node.js, nous allons commencer par utiliser leur version synchrone. Dans les exercices suivants, nous transformerons progressivement ce code synchrone en code asynchrone, afin de pouvoir les intégrer à notre chat-bot.
Écrivez un programme Node.js nommé minuscules.js
qui:
- récupère dans une variable le contenu d'un fichier dont le chemin d'accès est fourni en argument de ligne de commande;
- remplace toutes les lettres majuscules de ce contenu par des minuscules, en modifiant cette variable;
- affiche le contenu de cette variable, après l'avoir modifiée;
- puis écrit ce contenu modifié dans le fichier
résultat.txt
.
👉 Exerciseur en ligne: ici
🤖 Execution du robot de correction en local:
$ npm install github:adrienjoly/cours-nodejs # une fois pour toutes, pour installer le robot
$ npx cours-nodejs test 3-1 minuscules.js # pour faire tester minuscules.js au robot de l'exercice 1 de la partie 3
Références Node.js et JavaScript utiles:
fs.readFileSync()
,fs.writeFileSync()
,<string>.toLowerCase()
- How to parse command line arguments | Node.js.
Dupliquer puis modifier le programme minuscules.js
de l'exercice précédent, en utilisant cette fois les fonctions asynchrones readFile()
et writeFile()
au lieu de readFileSync()
et writeFileSync()
.
Intercepter les erreurs qui pourraient survenir lors de l'écriture ou de la lecture de fichiers, et les afficher dans la sortie d'erreurs.
👉 Exerciseur en ligne: ici
🤖 Execution du robot de correction en local:
$ npx cours-nodejs test 3-2 minuscules.js
Références Node.js et JavaScript utiles:
Dupliquer puis modifier le programme minuscules.js
de l'exercice précédent.
Définir une fonction lireFichier()
qui acceptera deux paramètres: le nom de fichier à lire et une fonction callback. Cette fonction intermédiaire sera responsable de lire le fichier passé en paramètre, puis de transmettre son contenu à la fonction callback.
Faites en sorte que:
- la transformation du contenu ainsi que l'écriture du fichier
résultat.txt
soit effectués en dehors de la fonctionlireFichier()
; - la fonction
readFile()
ne soit appelée que par votre fonctionlireFichier()
; - votre fonction
lireFichier()
appelle la fonctioncallback
qui lui aura été passée en paramètre, dès que la lecture sera terminée; - si la lecture a échoué, appeler
callback(err)
, où le paramètreerr
représente l'erreur en question; - sinon, appeler
callback(null, contenu)
, où le paramètrecontenu
représente le texte qui a été lu dans le fichier.
Après ces modifications, le programme doit fonctionner de manière identique à celui de l'exercice précédent.
👉 Exerciseur en ligne: ici
🤖 Execution du robot de correction en local:
$ npx cours-nodejs test 3-3 minuscules.js
Dupliquer puis modifier le programme minuscules.js
de l'exercice précédent, en utilisant des Promesses au lieu des callback dans tous les appels et définitions de fonctions asynchrones. Vous devrez implémenter la lecture du fichier en définissant la fonction lireFichier(nomFichier)
.
Après ces modifications:
- votre programme ne doit donc plus employer de callback;
- et il doit fonctionner de manière identique à celui de l'exercice précédent.
👉 Exerciseur en ligne: ici
🤖 Execution du robot de correction en local:
$ npx cours-nodejs test 3-4 minuscules.js
Conseil: Commencez par transformer seulement l'appel à writeFile()
dans un premier temps, puis celui à lireFichier()
dans un deuxième temps.
Références Node.js et JavaScript utiles:
fs.promises.readFile()
fs.promises.writeFile()
- Aide-mémoire sur différents types de fonctions asynchrones et autres ressources fournies dans la partie 2.
Dupliquer puis modifier le programme minuscules.js
de l'exercice précédent, en utilisant des async
et await
au lieu des Promesses dans tous les appels et définitions de fonctions asynchrones. Vous devrez implémenter la lecture du fichier en définissant la fonction lireFichier(nomFichier)
.
Après ces modifications:
- votre programme ne doit donc plus employer
Promise
,resolve
,reject
,.then()
,.catch()
ni de callback; - et il doit fonctionner de manière identique à celui de l'exercice précédent.
👉 Exerciseur en ligne: ici
🤖 Execution du robot de correction en local:
$ npx cours-nodejs test 3-5 minuscules.js
Conseil: Commencez par transformer seulement l'appel à writeFile()
dans un premier temps, puis celui à lireFichier()
dans un deuxième temps.
Dans la partie 1 du cours, nous avons créé un serveur web dont l'API contient les points d'entrée (endpoints) suivants:
GET /
retourne systématiquement "Hello World".GET /hello
retourne une salutation personnalisée.POST /chat
retourne une réponse en fonction de la valeur de la propriétémsg
passée au format JSON.
Nous voulons désormais que notre chat-bot soit capable d'apprendre de nouvelles informations lors des échanges avec les utilisateurs, et d'exploiter ces informations pour mieux répondre lors des prochains échanges.
Exemples de conversation / cas d'usage:
$ curl -X POST --header "Content-Type: application/json" --data "{\"msg\":\"demain\"}" "http://localhost:3000/chat"
répondra "Je ne connais pas demain..."$ curl -X POST --header "Content-Type: application/json" --data "{\"msg\":\"demain = Mercredi\"}" "http://localhost:3000/chat"
répondra "Merci pour cette information !"$ curl -X POST --header "Content-Type: application/json" --data "{\"msg\":\"demain\"}" "http://localhost:3000/chat"
répondra "demain: Mercredi" (y compris après redémarrage du serveur)
Pour cela, nous allons:
- enregistrer toute nouvelle information dans un fichier
réponses.json
, - pour chaque requête reçue, chercher si le fichier contient la réponse correspondante.
Exigences:
- Le code ne doit pas faire plus de 50 lignes.
- Le serveur doit pouvoir s'exécuter même si le fichier
réponses.json
n'existe pas.- Utiliser les mots clés
async
etawait
pour définir et appeler toute fonction asynchrone. (au lieu dePromise
,resolve
,reject
,.then()
et.catch()
)- Couvrir les cas d'erreurs tel que décrit dans les exercices précédents.
- En cas d'erreur lors de l'écriture du fichier, envoyer la réponse suivante à la requête: "
Oops, je n'ai pas pu enregistrer cette information. Merci de réessayer.
"
- Faire en sorte que le point d'entrée
/chat
enregistre la clé (ex: "demain") et la valeur (ex: "Mercredi") fournies par l'utilisateur dans la fichierréponses.json
, lorsque celui-ci fournit une nouvelle information. (étape 2 du cas d'usage) - Faire en sorte que, après avoir fourni une information, l'utilisateur puisse retrouver cette information en formulant une requête (cf étape 3 du cas d'usage), grâce au fichier
réponses.json
. - Faire en sorte que toutes les étapes du cas d'usage fonctionne, plusieurs fois d'affilée, y compris avec d'autres mots que "demain" et d'autres valeurs que "Mercredi". S'assurer que les nouvelles informations sont encore exploitables même après avoir redémarré le serveur.
- Faites en sorte que le fichier
réponses.json
puisse retenir plus d'une information à la fois.
- Archivage des conversations dans plusieurs fichiers (un par interlocuteur)
- cf Aide-mémoire et autres ressources sur l'exécution de code asynchrone fournies dans la partie 2.