M2 Miage NTDP et MBDS : Server Side JS, MongoDB, frameworks JS

De $1

Version de 23:34, 26 Mai 2020

cette version.

Revenir à liste des archives.

Voir la version actuelle

Introduction

Cette année on va voir NodeJS/MongoDB/REST WS/Clients JS.

Séance 1 - présentation de NodeJS et premiers exercices simples

Ressource : des MOOCS!

Il y a d'excellents cours JS avancés sur udacity.com (je recommande pour ceux qui se débrouillent pas mal celui-ci: https://www.udacity.com/course/objec...ascript--ud015)

Outils à installer

  • Un bon éditeur de code prêt pour le dev front-end: sublime text 3, visual studio code, atom, etc. Pensez à installer les packages emmet, babel, etc.
  • Si vous êtes sous windows, un bon terminal, acceptant le copier/coller, la colorisation, le multi-onglet ou multi-fenêtre, par exemple http://cmder.net/, powershell (de microsoft, déjà installé sous win10), hyperterminal (payant), console2, powercmd, colorconsole, mobaextrem, terminal wings, conemu, 

TP - routage avec le module ExpressJS, Web Services RESTFUL

Supports de cours: transparents de présentation de Express 

  • TP:
    1.  Récupérez cette archive, dezippez là quelque part, avec la ligne de commande, faites cd dans le répertoire TP_ROUTAGE_EXPRESS_CRUD_AJAX créé, et exécutez la commande "npm install".

      Ceci devrait créer un sous directory node_modules contenant les modules nécessaires (dans notre cas: express et multer).
       
    2. Suivez les consignes du prof et les explications au tableau.
    3. Les bonnes pratiques pour créer une API RESThttps://blog.octo.com/designer-une-api-rest/

    4. FACULTATIF: Avec Multer on peut aussi uploader des fichiers Testez cet exemple qui fait de l'upload de fichiers. Pensez à installer les modules express et multer dans le répertoire avant d'exécuter.

TP - MongoDB

  • Vous allez, dans cette séance apprendre les bases de l'utilisation de MongoDB depuis une application écrite en JavaScript et exécutée avec NodeJS. Dans un second temps, vous ré-utiliserez le code qui fait le CRUD sur une base d'exemples de MongoDB, en le déplaçant dans des méthodes app.get, app.post etc du TP de la séance 3, pour faire une application utilisable depuis des URLs.

1 - Installer MongoDB sur votre machine

Suivez les installations propres à votre système d'exploitation situées sur cette page du site officiel. Ne choisissez pas l'installation manuelle.

Une fois installé lancez la commande "mongod" en ligne de commande. Si le daemon mongoDB ne se lance pas, regardez les erreurs.

Sur mon Mac j'ai fait:

  • brew update
  • brew install mongodb
  • mkdir -p /data/db
  • chmod 777 /data/db (pour autoriser un user lambda à écrire dedans)
  • mongod (pour exécuter MongoDB)

2 - Créer et peupler une collection par défaut (avec un dataset issu du tutorial MongoDB officiel)

  • Suivre les instructions situées sur cette page. Vous allez devoir récupérer le fichier primer-dataset.json (assez gros, attention, ne pas faire copier/coller), et exécuter la commande suivante, qui créer une bd "test" et ajoute dedans la collection "restaurants" :
    • mongoimport --db test --collection restaurants --drop --file primer-dataset.json
  • Une fois l'importation faite, garder l'onglet ouvert sur cette page, car on va continuer le tutorial à l'étape 5.

3 - Installer un outil d'administration sympa

Je vous recommande fortement MongoChef, un produit commercial mais gratuit pour utilisation non commerciale. Le télécharger sur: https://studio3t.com/

4 - Ouvrir 3T STudio et voir la collection que l'on vient d'importer

  • S'assurer que MongoDB tourne (mongod doit être lancé, ou bien vous devez avoir installé MongoDB en service)
  • Lancer l'application 3T Studio, connectez-vous sur MongoDB. Les valeurs par défaut doivent être Ok, normalement.
  • Ouvrir la collection "restaurants" dans la base "test"

Quelques screenshots:

MongoChef1.jpg

MongoChefRequestBuilder.jpg 

5 - Installer le driver MongoDB pour NodeJS

  • Créez un répertoire tpmongo
  • cd tpmongo
  • npm install mongodb

Ca doit télécharger le module driver mongodb dans un sous-répertoire node_modules.

6 - Tester des requêtes CRUD avec NodeJS et express   

  • serverCrudWithMongo.js 
     
  • Et un autre à mettre dans un sous répertoire app_modules: crud-mongo.js 
  • Allez dans le répertoire du TP précédent fait avec juste express (avec serverCrud.js), et copiez les deux fichiers précédents dedans, mais mettez crud-mongo.js dans un sous -répertoire app_modules.
  • Faites npm install -save mongodb
  • executez node serverCrudWithMongo (ou nodemon)

Ecriture d'un client de test utilisant Ajax/Fetch API et l'API des tableaux HTML5

  • Telechargez le fichier suivant: crudAvecFetchAvecTable.js 
  • Mettez-le à côté du fichier public/js/crudAvecFetch.js
  • Modifier le nom du fichier à inclure dans public/index.html et ajoutez l'attribut id="formulaireModification" dans le formulaire de modification du PUT
  • Executez node serverCrudWithMongo.js
  • Etudiez le code, regardez en particulier comment, quand on clique sur le premier bouton GET AJAX un tableau est construit dynamiquement. 
  • Etudiez ce que le prof a fait en live coding: la suppression et la modification d'une donnée.

A FAIRE : essayer d'ajouter un findByName et un count à l'application précédente.

Corrections pour le count et pour le findByName:

Voir la doc de MongoDB pour les requêtes comprenant des expressions régulières: https://docs.mongodb.com/manual/refe...r/query/regex/

Dans serverCrudWithMongo.js:

// ICI c'est autorisé par la norme REST car
// "count" est un mot réservé, on ne risque pas de
// le prendre pour une TABLE ou une collection
// cf la partie "reserved words" de
// https://blog.octo.com/designer-une-api-rest/
app.get('/api/restaurants/count', function(req, res) { 
	// on renvoie le nombre de restaurants
 	mongoDBModule.countRestaurants(function(data) {
 		var objdData = {
 			msg:"Count effectué avec succès",
 			data: data
 		}
 		res.send(JSON.stringify(objdData)); 
 	});     	
});

// On va récupérer des restaurants par un GET (standard REST) 
// cette fonction d'API peut accepter des paramètres
// pagesize = nombre de restaurants par page
// page = no de la page
// Oui, on va faire de la pagination, pour afficher
// par exemple les restaurants 10 par 10
app.get('/api/restaurants', function(req, res) { 
	// Si présent on prend la valeur du param, sinon 1
    let page = parseInt(req.query.page || 0);
    // idem si present on prend la valeur, sinon 10
    let pagesize = parseInt(req.query.pagesize || 10);
    let nom = req.query.nom;

	if(nom) {
    	// find by name
	 	mongoDBModule.findRestaurantsByName(nom, page, pagesize, function(data) {
	 		var objdData = {
	 			msg:"restaurant recherchés par nom avec succès",
	 			data: data
	 		}
	 		res.send(JSON.stringify(objdData)); 
	 	}); 
    } else {
    	// find normal
	 	mongoDBModule.findRestaurants(page, pagesize, function(data) {
	 		var objdData = {
	 			msg:"restaurant recherchés avec succès",
	 			data: data
	 		}
	 		res.send(JSON.stringify(objdData)); 
	 	}); 

    }
});

Dans app_modules/crud-mongo.js:

exports.countRestaurants = function(callback) {
	console.log("DANS COUNT")
	MongoClient.connect(url, function(err, db) {
		db.collection('restaurants')
		.count(function(err, res) {
			console.log("COUNT = " + res)
			callback(res);
		});
	});
};

exports.findRestaurantsByName = function(nom,page, pagesize, callback) {
    MongoClient.connect(url, function(err, db) {
    	    console.log("pagesize = " + pagesize);
    	    console.log("page = " + page);
    console.log("FIND BY NAME nom=" + nom);

    	// syntaxe recommandée
    	// Cf doc mongodb: https://docs.mongodb.com/manual/reference/operator/query/regex/
    	// The $regex value needs to be either the string 
    	// pattern to match or a regular expression object. 
    	// When passing a string pattern, you don't include 
    	// the / delimitters
    	// VERSION avec $regexp et $options
    	let myquery = {
    		"name": {
    			$regex: ".*" + nom + ".*", 
    			$options:"i"
    		}
    	}

    	// VERSION avec objet RegExp
    	//let myquery =  {'name' : new RegExp('^.*'+nom+'.*$',"i")};
    	// ou, si on veut être "case sensitive"  
    	//let myquery =  {'name' : new RegExp('^.*'+nom+'.*$')};
        if(!err){
            db.collection('restaurants')
            .find(myquery)
            .skip(page*pagesize)
            .limit(pagesize)
            .toArray()
            .then(arr => callback(arr));
        }
        else{
            callback(-1);
        }
    });
};

 

     

Séance 3: rappels JavaScript objet et asyncrhone, introduction aux frameworks

Les classes ou pseudo classes en JavaScript

  • A FAIRE : vous inscrire au MOOC JavaScript Intro, les objets sont détaillés tout au long du MOOC, mais pour gagner du temps, le plus intéressant est dans le module 4 et le module 5. Ce cours d'intro ne parle pas de l'héritage ou de design patterns. C'est pourquoi je vous donne des exemples ci-dessous que nous détaillerons en classe.

Ressources pour l'héritage :

  • Le plus simple pour commencer est de tester des exemples simples que je vous ai préparé sur JsBin:
  • ES5 :
    1. Exemple 1 qui couvre les cas "classiques" : classes et sous-classes, héritage de propriété et de méthodes. Différentes syntaxe d'appel des constructeurs hérités (avec et sans utilisation de la méthode call)

       
    2. Exemple 2 qui montre comment redéfinir une méthode héritée sans changer son nom, et en gardant la possibilité d'appeler la méthode de la classe dont on hérite (équivalent du super.methode...)
       
    3. Exemple 3 avec le Black Box model (qui n'est pas de l'héritage mais de la composition, on peut quand même simuler l'héritage et la redéfinition, vous verrez, mais l'opérateur instanceof ne donnera plus l'appartenance des instances à plusieurs types en même temps).
       
    • Pour en savoir plus sur la l'héritage et la définition de pseudo-classes avec la syntaxe JavaScript classique, voir ce cours en français sur le Mozilla Developer Network

Introduction aux frameworks

Une todolist en différentes versions JS/jQuery/VueJS/VueJS + fetch API:

Introduction à ReactJS

A faire avant le TP:

  1. Vous devez avoir nodeJS correctement installé (node, npm, etc, tout ceci doit fonctionner...)
     
  2. Installer l'extension Google Chrome "React Developer Tools" (https://chrome.google.com/webstore/d...jfkapdkoienihi), elle existe aussi pour Firefox
     
  3. Installer une bonne fenêtre terminal pour Windows, si vous êtes sous windows, comme Hyperterminal ou http://cmder.net/
     
  4. Installer les package "babel" et "emmet" pour Sublime Text 3 ou pour Atom, selon l'éditeur de code que vous utilisez
     
  5. Récupérez les sources du cours React (cd dans le répertoire du TP -creez-le!- et exécutez git clone https://github.com/wesbos/React-For-...-Starter-Files)
     
  6. Ouvrir la ligne de commande et exécuter la commande "npm install -g create-react-app",
    • Pour vérifier que ça fonctionne, créez un autre répertoire nommé "helloWorld" et cd dedans,
    • executer "create-react-app hello-world" (ça prend du temps, quelques minutes)...
    • Allez dans le répertoire créé (cd hello-world), et faites "npm install" (là aussi, quelques minutes)
    • Exécutez le progralle en tapant "npm start", ça doit ouvrir automatiquement le browser sur le port 3000 et afficher une page avec le logo React qui tourne.
    • Editez le code du fichier src/App.js, changez le texte et sauvez -> la page Web de l'application doit se rafraichir automatiquement.

A faire pour la séance de vendredi :