Skip to content

Latest commit

 

History

History
201 lines (129 loc) · 11 KB

index.md

File metadata and controls

201 lines (129 loc) · 11 KB
title layout
Partie 3 - Utilisation du système de fichiers
default

Objectifs de cette partie

  • 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 et async + 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.


Introduction

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.


Exercice 1 - Lecture et écriture synchrone

É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:


Exercice 2 - Utilisation d'appels asynchrones

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:


Exercice 3 - Création d'une fonction intermédiaire avec callback

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 fonction lireFichier();
  • la fonction readFile() ne soit appelée que par votre fonction lireFichier();
  • votre fonction lireFichier() appelle la fonction callback 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ètre err représente l'erreur en question;
  • sinon, appeler callback(null, contenu), où le paramètre contenu 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

Exercice 4 - Utilisation de Promesses

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:


Exercice 5 - Utilisation de async et await

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.


Exercice 6 - Chat-bot avec mémoire

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:

  1. $ curl -X POST --header "Content-Type: application/json" --data "{\"msg\":\"demain\"}" "http://localhost:3000/chat" répondra "Je ne connais pas demain..."
  2. $ curl -X POST --header "Content-Type: application/json" --data "{\"msg\":\"demain = Mercredi\"}" "http://localhost:3000/chat" répondra "Merci pour cette information !"
  3. $ 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 et await pour définir et appeler toute fonction asynchrone. (au lieu de Promise, 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."

Étapes proposées

  1. 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 fichier réponses.json, lorsque celui-ci fournit une nouvelle information. (étape 2 du cas d'usage)
  2. 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.
  3. 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.
  4. Faites en sorte que le fichier réponses.json puisse retenir plus d'une information à la fois.

Références Node.js et JavaScript


Exercices bonus

  • Archivage des conversations dans plusieurs fichiers (un par interlocuteur)

Références