Si vous ne faites que commencer avec Node.js et que vous voulez vous lancer dans la création d'une application Web, les choses peuvent souvent devenir un peu écrasantes. Une fois que vous avez dépassé les tutoriels "Bonjour, monde!", Une grande partie du contenu vous propose de copier-coller du code, avec peu ou pas d'explications sur ce que vous faites ou pourquoi.
Quand vous avez fini, vous avez construit quelque chose de sympa et brillant, mais vous avez aussi relativement peu de choses à retenir que vous pouvez appliquer à votre prochain projet.
Dans ce tutoriel, je vais adopter une approche légèrement différente. En partant de zéro, je vais vous montrer comment créer une application web simple en utilisant Node.js, mais au lieu de me concentrer sur le résultat final, je vais me concentrer sur une série de choses que vous pourriez rencontrer lors de la construction. une application du monde réel. Cela inclut le routage, la création de modèles, le traitement des formulaires, l'interaction avec une base de données et même l'authentification de base.
Ce ne sera pas un JavaScript 101. Si c'est le genre de chose que vous cherchez, . Il sera, cependant, approprié pour ceux qui se sentent raisonnablement confiants avec le langage Javascript, et qui cherchent à faire leurs premiers pas dans Node.js.
Ce que nous construirons
Nous utiliserons Node.js et le framework Express pour construire un formulaire d'inscription simple avec validation de base, qui conserve ses données dans une base de données MongoDB . Nous allons ajouter une vue pour répertorier une inscription réussie, que nous protégerons avec une authentification HTTP de base, et nous utiliserons Bootstrap pour ajouter du style. Le tutoriel est structuré pour que vous puissiez suivre étape par étape. Cependant, si vous voulez aller de l'avant et voir le résultat final, le code de ce tutoriel est également disponible sur GitHub .
Configuration de base
Avant de pouvoir commencer à coder, nous allons besoin d'avoir Node, NPM et MongoDB installés sur nos machines. Je ne vais pas entrer dans les détails sur les différentes instructions d'installation, mais si vous avez des problèmes pour installer, laissez un commentaire ci-dessous, ou visitez nos forums et demandez de l'aide là-bas.
Noeud. js
De nombreux sites Web vous recommanderont de vous diriger vers la page officielle de téléchargement de nœuds et de récupérer les fichiers binaires de votre système. Alors que cela fonctionne, je suggère que vous utilisiez un gestionnaire de version à la place. C'est un programme qui vous permet d'installer plusieurs versions de Node et de basculer entre elles à volonté. L'utilisation d'un gestionnaire de versions présente divers avantages, par exemple, il supprime les problèmes d'autorisation potentiels qui vous empêcheraient d'installer des paquets avec des droits d'administrateur.
Si vous avez envie d'utiliser le gestionnaire de versions, consultez notre astuce: Installer Plusieurs versions de Node.js utilisant nvm . Sinon, récupérez les binaires appropriés pour votre système à partir du lien ci-dessus et installez ceux-ci.
npm
npm est un gestionnaire de paquets JavaScript livré avec Node, donc aucune installation supplémentaire n'est nécessaire ici. Nous allons utiliser assez largement npm tout au long de ce tutoriel, donc si vous avez besoin d'un rafraîchissement, veuillez consulter: Guide du débutant sur npm – le gestionnaire de paquetages de nœuds .
MongoDB [19659010] MongoDB est une base de données de documents qui stocke des données dans des documents flexibles de type JSON.
Le moyen le plus rapide de se lancer avec Mongo est d'utiliser un service tel que mLabs. Ils ont un plan de sandbox gratuit qui fournit une base de données unique avec 496 Mo de stockage en cours d'exécution sur une machine virtuelle partagée. C'est plus que suffisant pour une application simple avec une poignée d'utilisateurs. Si cela vous semble être la meilleure option, veuillez consulter leur guide de démarrage rapide .
Vous pouvez également installer Mongo localement. Pour ce faire, rendez-vous sur la page de téléchargement officielle et téléchargez la version correcte du serveur de communauté pour votre système d'exploitation. Il y a un lien vers des instructions d'installation détaillées, spécifiques à l'OS, sous chaque lien de téléchargement, que vous pouvez consulter en cas de problème.
Une interface graphique MongoDB
Bien que cela ne soit pas strictement nécessaire pour suivre ce tutoriel, pour installer Compass, l'interface graphique officielle de MongoDB . Cet outil vous aide à visualiser et à manipuler vos données, vous permettant d'interagir avec des documents dotés de la fonctionnalité CRUD complète.
Au moment de la rédaction, vous devrez remplir vos informations pour télécharger Compass, mais vous n'aurez pas besoin de créez un compte.
Vérifiez que tout est correctement installé
Pour vérifier que Node et npm sont correctement installés, ouvrez votre terminal et tapez:
node -v
suivi de:
npm -v
Cela affichera le numéro de version de chaque programme ( 8.9.4
et 5.6.0
respectivement au moment de la rédaction).
Si vous avez installé Mongo localement, vous peut vérifier le numéro de version en utilisant:
mongo --version
Cela devrait produire un tas d'informations, y compris le numéro de version ( 3.6.2
au moment de l'écriture).
Vérifier la connexion à la base de données avec la boussole
Si vous avez installé Mongo localement , vous démarrez le serveur en tapant la commande suivante dans un terminal:
mongod
Ensuite, ouvrez Compass. Vous devriez pouvoir accepter les valeurs par défaut (serveur: localhost
port: 27017), appuyez sur le bouton CONNECT et établissez une connexion au serveur de base de données.
MongoDB Compass connecté à localhost
Notez que les bases de données admin
et local
sont créées automatiquement.
Utilisation d'une solution hébergée dans le cloud
Si vous utilisez mLabs, créez un abonnement à la base de données (comme décrit dans leur guide de démarrage rapide ), puis copiez les détails de connexion dans le presse-papiers. Cela devrait être sous la forme:
mongodb: // : @ ds251827.mlab.com: 51827 /
Lorsque vous ouvrez Compass, il vous informe qu'il a détecté une chaîne de connexion MongoDB et vous demande si vous souhaitez l'utiliser pour remplir le formulaire. Cliquez sur Oui en notant que vous devrez peut-être ajuster manuellement le nom d'utilisateur et le mot de passe. Après cela, cliquez sur CONNECTER et vous devriez partir pour les courses
MongoDB Boussole connectée à mLabs [19659003] Notez que j'ai appelé ma base de données sp-node-article
. Vous pouvez appeler le vôtre ce que vous voulez.
Initialiser l'application
Avec tout ce que vous avez configuré correctement, la première chose à faire est d'initialiser notre nouveau projet. Pour ce faire, créez un dossier nommé demo-node-app
entrez ce répertoire et tapez ce qui suit dans un terminal:
npm init -y
Cela créera et remplira automatiquement un fichier package.json
dans la racine du projet. Nous pouvons utiliser ce fichier pour spécifier nos dépendances et pour créer plusieurs scripts npm ce qui facilitera notre processus de développement.
Installer Express
Express est un framework d'application web léger pour Node.js, qui nous fournit un ensemble robuste de fonctionnalités pour l'écriture d'applications web. Ces fonctionnalités incluent des éléments tels que la gestion des routes, l'intégration du moteur de gabarit et un framework de middleware, ce qui nous permet d'effectuer des tâches supplémentaires sur les objets de requête et de réponse. Il n'y a rien que vous puissiez faire dans Express que vous ne pourriez pas faire en Node.js, mais en utilisant Express, nous n'avons pas besoin de réinventer la roue et de réduire la plaque passante.
Alors installons Express [Listlist5listlist55list5listlist55list55<br>5listlistlist55listlist5list5listlist55Pourcefaireexécutezcequisuitdansvotreterminal:
npm install --save express
En passant l'option - save
à la commande npm install
Express sera ajouté à la section dépendances du
package.json
fichier. Cela signale à toute personne exécutant notre code que Express est un paquet dont notre application a besoin pour fonctionner correctement.
Installer nodemon
nodemon est un outil pratique. Il va regarder les fichiers dans le répertoire dans lequel il a été démarré, et s'il détecte des changements, il redémarrera automatiquement votre application Node (ce qui signifie que vous n'avez pas à le faire). Contrairement à Express, nodemon n'est pas quelque chose dont l'application a besoin pour fonctionner correctement (cela nous aide simplement au développement), alors installez-la en utilisant:
npm install --save-dev nodemon
Cela ajoutera nodemon à la section dev-dependencies
du fichier package.json
.
Créer des fichiers initiaux
Nous en avons presque fini avec la configuration . Tout ce que nous devons faire maintenant est de créer quelques fichiers initiaux avant de lancer l'application.
Dans le dossier demo-node-app
créez un fichier app.js
et un fichier start.js
. Créez également un dossier routes
avec un fichier index.js
à l'intérieur. Une fois que vous avez terminé, les choses devraient ressembler à ceci:
.
├── app.js
├── node_modules
│ └── ...
Package── package.json
├── itinéraires
Index └── index.js
└── start.js
Maintenant, ajoutons du code à ces fichiers.
Dans app.js
:
const exprime = require ('express');
const routes = require ('./ routes / index');
const app = express ();
app.use ('/', routes);
module.exports = app;
Ici, nous importons à la fois le module express
et (la valeur d'exportation de) notre fichier de routes dans l'application. La fonction nécessite
que nous utilisons pour faire ceci est une fonction de nœud intégrée qui importe un objet d'un autre fichier ou module. Si vous souhaitez un rappel sur l'importation et l'exportation de modules, lisez Présentation du module.exports et des exportations dans Node.js .
Ensuite, nous créons une nouvelle application Express en utilisant le exprimez la fonction et attribuez-la à une variable d'application
. Nous indiquons ensuite à l'application que, chaque fois qu'elle reçoit une requête de n'importe quelle barre oblique, elle doit utiliser le fichier routes.
Enfin, nous exportons notre variable d'application afin qu'elle puisse être importée et utilisée dans d'autres fichiers
start.js
:
const app = require ('./ app');
serveur const = app.listen (3000, () => {
console.log (`Express s'exécute sur le port $ {server.address (). port}`);
});
Ici, nous importons l'application Express que nous avons créée dans app.js
(notez que nous pouvons laisser le .js
sur le nom de fichier dans require
] déclaration). Nous disons alors à notre application d'écouter sur le port 3000 pour les connexions entrantes et de transmettre un message au terminal pour indiquer que le serveur est en cours d'exécution.
Et dans routes / index.js
:
const express = require ('express');
routeur const = express.Router ();
router.get ('/', (req, res) => {
res.send ('Ça marche!');
});
module.exports = routeur;
Ici, nous importons Express dans notre fichier de routes, puis nous en récupérons le routeur. Nous utilisons ensuite le routeur pour répondre à toutes les demandes à l'URL racine (dans ce cas http: // localhost: 3000
) avec un message "It works!"
Coup d'envoi de l'application
] Enfin, ajoutons un script npm pour que nodemon commence à regarder notre application. Modifiez la section scripts
du fichier package.json
pour ressembler à ceci:
"scripts": {
"watch": "nodemon ./start.js"
},
La propriété scripts
du fichier package.json
est extrêmement utile, car elle vous permet de spécifier des scripts arbitraires à exécuter dans différents scénarios. Cela signifie que vous n'avez pas besoin de taper à plusieurs reprises des commandes longues avec une syntaxe difficile à mémoriser. Si vous souhaitez en savoir plus sur ce que les scripts npm peuvent faire, lisez Give Grunt the Boot! Guide sur l'utilisation de npm en tant qu'outil de compilation .
Maintenant, tapez npm exécutez la surveillance
depuis le terminal et visitez http: // localhost: 3000 .
Vous devriez voir "Ça marche!"
Templating Basic avec Pug
Retourner une réponse en ligne depuis le gestionnaire d'itinéraire est très bien, mais ce n'est pas très extensible, et c'est là qu'interviennent les moteurs de templates. Docs exprès état:
Un moteur de modèle vous permet d'utiliser des fichiers de modèle statique dans votre application. Lors de l'exécution, le moteur de modèle remplace les variables d'un fichier modèle par des valeurs réelles et transforme le modèle en fichier HTML envoyé au client.
En pratique, cela signifie que nous pouvons définir des fichiers modèles d'écrire tout en ligne. Faisons-le maintenant.
Créez un dossier nommé views
et dans ce dossier un fichier nommé form.pug
. Ajoutez le code suivant à ce nouveau fichier:
form (action = "." Method = "POST")
label (for = "nom") Nom:
contribution(
type = "texte"
id = "nom"
name = "nom"
)
label (for = "email") Email:
contribution(
type = "email"
id = "email"
name = "email"
)
input (type = "submit" value = "Soumettre")
Comme vous pouvez le déduire de la fin du fichier, nous utiliserons le pug templating engine dans notre application. Pug (anciennement connu sous le nom de Jade) est livré avec sa propre syntaxe sensible à l'indentation pour écrire du HTML dynamique et réutilisable. Heureusement, l'exemple ci-dessus est facile à suivre, mais si vous avez des difficultés à comprendre ce qu'il fait, attendez que nous l'ayons vu dans un navigateur, puis inspectez la source de la page pour voir le balisage qu'elle produit.
un rappel sur ce que sont les templates JavaScript et / ou les moteurs de templates, et quand vous devriez les utiliser, lisez Une vue d'ensemble des moteurs de template JavaScript
Installer Pug et l'intégrer dans l'application Express
Ensuite, nous aurons besoin d'installer pug, en l'enregistrant comme une dépendance:
npm i --save pug
Configurez ensuite app.js
pour utiliser Pug comme moteur de mise en page et rechercher des modèles dans le dossier views
:
const express = require ('express');
const path = require ('chemin');
const routes = require ('./ routes / index');
const app = express ();
app.set ('views', path.join (__ dirname, 'views'));
app.set ('view engine', 'pug');
app.use ('/', routes);
module.exports = app;
Vous remarquerez que nous avons également besoin du module de chemin natif de Node qui fournit des utilitaires pour travailler avec les chemins de fichiers et de répertoires. Ce module nous permet de construire le chemin vers notre dossier views
en utilisant sa méthode de jointure et __ dirname (qui retourne le répertoire dans lequel réside le script en cours d'exécution).
Modifier la route pour utiliser notre modèle
Enfin, nous devons indiquer notre route pour utiliser notre nouveau modèle. Dans routes / index.js
:
router.get ('/', (req, res) => {
res.render ('formulaire');
});
Cela utilise la méthode de rendu sur l'objet de réponse d'Express pour envoyer la vue rendue au client.
Voyons donc si cela a fonctionné. Comme nous utilisons nodemon pour regarder notre application pour les changements, vous devriez simplement pouvoir actualiser votre navigateur et voir notre chef-d'œuvre brutaliste.
Définir un fichier de mise en page pour le roquet
Si vous ouvrez votre navigateur et inspectez la source de la page , vous verrez qu'Express n'a envoyé que le HTML pour le formulaire: il manque à notre page une déclaration de type doc, ainsi qu'une section head et body. Corrigeons cela en créant une maquette pour tous nos modèles à utiliser.
Pour ce faire, créez un fichier layout.pug
dans le dossier views
et ajoutez le code suivant:
doctype html
html
tête
title = `$ {titre}`
corps
h1 Mon application incroyable
bloquer le contenu
La première chose à remarquer ici est la ligne commençant title =
. L'ajout d'un signe égal à un attribut est l'une des méthodes que Pug utilise pour l'interpolation. Vous pouvez en lire plus à ce sujet ici . Nous allons l'utiliser pour transmettre le titre dynamiquement à chaque modèle.
La deuxième chose à noter est la ligne qui commence par le mot-clé
. Dans un modèle, un bloc est simplement un "bloc" de Pug qu'un modèle enfant peut remplacer. Nous verrons comment l'utiliser sous peu, mais si vous souhaitez en savoir plus, lisez cette page sur le site Web de Pug .
Utilisez le fichier de mise en page du modèle enfant
ce qui reste à faire est d'informer notre modèle form.pug
qu'il doit utiliser le fichier layout. Pour ce faire, modifiez views / form.pug
comme suit:
extends layout
bloquer le contenu
form (action = "." method = "POST")
label (for = "nom") Nom:
contribution(
type = "texte"
id = "nom"
name = "nom"
)
label (for = "email") Email:
contribution(
type = "email"
id = "email"
name = "email"
)
input (type = "submit" value = "Soumettre")
Et dans routes / index.js
nous devons passer un titre approprié pour le gabarit à afficher:
router.get ('/', (req, res) => {
res.render ('formulaire', {titre: 'Formulaire d'inscription'});
});
Maintenant, si vous actualisez la page et inspectez la source, les choses devraient être beaucoup mieux.
Traiter les formulaires dans Express
Actuellement, si vous cliquez sur le bouton Soumettre de notre formulaire, ll sera redirigé vers une page avec un message: "Can not POST /". Ceci est dû au fait que notre formulaire POSTUE son contenu à /
et que nous n'avons pas encore défini de route pour le faire.
Faisons-le maintenant. Ajoutez ce qui suit à routes / index.js
:
router.post ('/', (req, res) => {
res.render ('formulaire', {titre: 'Formulaire d'inscription'});
});
C'est la même chose que notre route GET, sauf que nous utilisons router.post
pour répondre à un verbe HTTP différent.
Maintenant, quand nous soumettons le formulaire, l'erreur le message sera parti et le formulaire devrait simplement être rendu à nouveau.
Handle Form Input
La tâche suivante consiste à récupérer toutes les données que l'utilisateur a soumises via le formulaire. Pour ce faire, nous devrons installer un paquet nommé body-parser qui rendra les données de formulaire disponibles sur le corps de la requête:
npm install --save body-parser
Nous devrons aussi dire à notre application d'utiliser ce paquet, donc ajoutez ce qui suit à app.js
:
const bodyParser = require ('body-parser');
...
app.use (bodyParser.urlencoded ({extended: true}));
app.use ('/', routes);
module.exports = app;
Notez qu'il existe plusieurs façons de formater les données que vous POST sur le serveur, et en utilisant la méthode urlencoded de body-parser, nous pouvons gérer les données envoyées sous application / x-www-form- urlencoded
.
Ensuite, nous pouvons essayer de consigner les données soumises au terminal. Modifiez le gestionnaire d'itinéraire comme suit:
router.post ('/', (req, res) => {
console.log (req.body);
res.render ('formulaire', {titre: 'Formulaire d'inscription'});
});
Maintenant, quand vous soumettez le formulaire, vous devriez voir quelque chose comme:
{name: 'Jim', email: 'jim@example.com'}
Sortie de formulaire enregistrée sur le terminal
Remarque sur les objets de requête et de réponse
Vous avez peut-être déjà remarqué le modèle utiliser pour gérer les routes dans Express.
router.METHOD (route, (req, res) => {
// fonction de rappel
});
La fonction de rappel est exécutée chaque fois que quelqu'un visite une URL qui correspond à l'itinéraire spécifié. Le rappel reçoit un paramètre req
et res
où req
est un objet plein d'informations entrantes (telles que des données de formulaire ou des paramètres de requête) et res
est un objet plein de méthodes pour renvoyer des données à l'utilisateur. Il existe également un paramètre facultatif suivant
qui est utile si vous ne voulez pas renvoyer de données, ou si vous voulez passer la demande à autre chose pour gérer autre chose.
Sans être trop profond dans les mauvaises herbes, c'est un concept connu sous le nom de middleware (spécifiquement, intergiciel de niveau routeur) qui est très important dans Express. Si vous souhaitez en savoir plus sur la façon dont Express utilise le middleware, je vous recommande de lire les docs Express
Validating Form Input
Vérifions maintenant que l'utilisateur a rempli nos deux champs . Nous pouvons le faire en utilisant le module express-validator un middleware qui fournit un certain nombre de méthodes utiles pour la désinfection et la validation des entrées utilisateur.
Vous pouvez l'installer comme ceci:
npm install express -validator --save
Et nécessitent les fonctions dont nous aurons besoin dans routes / index.js
:
const {corps, validationRésultat} = require ('express-validator / check');
Nous pouvons l'inclure dans notre gestionnaire d'itinéraire comme suit:
router.post ('/',
[
body('name')
.isLength({ min: 1 })
.withMessage('Please enter a name'),
body('email')
.isLength({ min: 1 })
.withMessage('Please enter an email'),
],
(req, res) => {
...
}
)
Comme vous pouvez le voir, nous utilisons la méthode du corps pour valider deux propriétés sur req.body
- à savoir, name
et email
. Dans notre cas, il suffit de vérifier que ces propriétés existent (c'est-à-dire qu'elles ont une longueur supérieure à un), mais express-validator offre une foule d'autres méthodes que vous pouvez lire sur la page d'accueil du projet
Dans un deuxième temps, nous pouvons appeler la méthode validationResult pour voir si la validation a réussi ou échoué. Si aucune erreur n'est présente, nous pouvons aller de l'avant et afficher un message «Merci de vous inscrire». Sinon, nous devrons renvoyer ces erreurs à notre modèle, afin d'informer l'utilisateur que quelque chose ne va pas.
Et si la validation échoue, nous devrons également passer req.body
au modèle, de sorte que toutes les entrées de formulaire valides ne soient pas réinitialisées:
router.post (
'/',
[
...
],
(req, res) => {
const errors = validationResult (req);
if (errors.isEmpty ()) {
res.send ('Merci pour votre inscription!');
} autre {
res.render ('formulaire', {
titre: "Formulaire d'inscription",
erreurs: errors.array (),
list list list list list 5 list list list list 5 list list list 5 list list 5 list list 5 5 list 5 5 list 5 5 list 5 5 5
});
}
}
)
Nous devons maintenant apporter quelques modifications à notre modèle form.pug
. Nous devons d'abord vérifier une propriété errors
et si elle est présente, boucle sur les erreurs et les afficher dans une liste:
étend la mise en page
bloquer le contenu
si des erreurs
ul
pour erreur dans les erreurs
li = erreur.msg
...
Si le li =
semble bizarre, rappelez-vous que carg fait une interpolation en suivant le nom du tag avec un signe égal.
Enfin, nous devons vérifier si un attribut data
existe, et si c'est le cas, utilisez-le pour définir les valeurs des champs respectifs. S'il n'existe pas, nous l'initialiserons à un objet vide, de sorte que le formulaire s'affichera correctement lorsque vous le chargerez pour la première fois. Nous pouvons le faire avec du JavaScript, noté Pug par un signe moins:
-data = data || {}
Nous référençons ensuite cet attribut pour définir la valeur du champ:
input (
type = "texte"
id = "nom"
name = "nom"
value = data.name
)
Cela nous donne ce qui suit:
étend la mise en page
bloquer le contenu
list 5 5 list 5 5 5 list 21 5 5 5 list list 5 5 5 5 list 5 list 5 5 21 5 list 5 list 5 5 5 5 {}
si des erreurs
ul
pour erreur dans les erreurs
li = erreur.msg
form (action = "." method = "POST")
label (for = "nom") Nom:
contribution(
type = "texte"
id = "nom"
name = "nom"
value = data.name
)
label (for = "email") Email:
contribution(
type = "email"
id = "email"
name = "email"
valeur = data.email
)
input (type = "submit" value = "Soumettre")
Maintenant, lorsque vous soumettez une inscription réussie, vous devriez voir un message de remerciement, et lorsque vous soumettez le formulaire sans remplir les deux champs, le modèle devrait être re-rendu avec un message d'erreur.
Interagir avec un Base de données
Nous voulons maintenant accrocher notre formulaire à notre base de données, afin que nous puissions sauvegarder toutes les données que l'utilisateur entre. Si vous exécutez Mongo localement, n'oubliez pas de démarrer le serveur avec la commande mongod
.
Spécifiez les détails de la connexion
Nous aurons besoin d'un emplacement pour spécifier les détails de connexion à la base de données. Pour cela, nous allons utiliser un fichier de configuration (que ne devrait pas être vérifié dans le contrôle de version) et le paquet dotenv . Dotenv chargera nos détails de connexion à partir du fichier de configuration dans process.env de Node .
Installez-le comme ceci:
npm install dotenv --save
Et l'exige en haut de start.js
:
require ('dotenv'). Config ();
Ensuite, créez un fichier nommé .env
dans la racine du projet (notez que le démarrage d'un nom de fichier avec un point peut le masquer sur certains systèmes d'exploitation) et entrez vos détails de connexion Mongo le premier line.
Si vous exécutez Mongo localement:
DATABASE = mongodb: // localhost: 27017 / node-demo-application
Si vous utilisez mLabs:
mongodb: // : @ ds251827.mlab.com: 51827 /
Notez que les installations locales de MongoDB n'ont pas d'utilisateur ou de mot de passe par défaut. C'est certainement quelque chose que vous voudrez changer en production, car c'est un risque de sécurité.
Connexion à la base de données
Pour établir la connexion à la base de données et y effectuer des opérations, nous utiliserons Mangouste . Mongoose est un ORM pour MongoDB, et comme vous pouvez le lire sur la page d'accueil du projet :
Mongoose fournit une solution simple basée sur un schéma pour modéliser vos données d'application. Cela inclut le lancement de type intégré, la validation, la création de requêtes, les crochets de logique métier et bien plus encore.
Concrètement, cela crée différentes abstractions sur Mongo, ce qui facilite l'interaction avec notre base de données. réduire la quantité de passe-partout que nous devons écrire. Si vous souhaitez en savoir plus sur le fonctionnement de Mongo, lisez notre Introduction à MongoDB .
Pour installer Mongoose:
npm install --save mongoose
Puis, l'exiger dans start.js
:
const mongoose = require ('mongoose');
La connexion est faite comme suit:
mongoose.connect (process.env.DATABASE, {useMongoClient: true});
mongoose.Promise = global.Promise;
mongoose.connection
.on ('connected', () => {
console.log (`Connexion Mongoose ouverte sur $ {process.env.DATABASE}`);
})
.on ('erreur', (erreur) => {
console.log (`Erreur de connexion: $ {err.message}`);
});
Notez comment nous utilisons la variable DATABASE
que nous avons déclarée dans le fichier .env
pour spécifier l'URL de la base de données. Nous demandons également à Mongo d'utiliser ES6 Promises (ce qui est nécessaire car les interactions de la base de données sont asynchrones), car sa propre bibliothèque de promesses par défaut est obsolète.
Voici à quoi devrait ressembler start.js
:
require ('dotenv'). Config ();
const mongoose = require ('mongoose');
mongoose.connect (process.env.DATABASE, {useMongoClient: true});
mongoose.Promise = global.Promise;
mongoose.connection
.on ('connected', () => {
console.log (`Connexion Mongoose ouverte sur $ {process.env.DATABASE}`);
})
.on ('erreur', (erreur) => {
console.log (`Erreur de connexion: $ {err.message}`);
});
const app = require ('./ app');
serveur const = app.listen (3000, () => {
console.log (`Express s'exécute sur le port $ {server.address (). port}`);
});
Lorsque vous enregistrez le fichier, nodemon redémarre l'application et, si tout s'est bien passé, vous devriez voir quelque chose comme:
Connexion Mongoose ouverte sur mongodb: // localhost: 27017 / node-demo-application
Définir un schéma Mongoose
MongoDB peut être utilisé comme une base de données libre, ce qui signifie qu'il n'est pas nécessaire de décrire à quoi ressembleront les données à l'avance. Cependant, dès la sortie de la boîte, il fonctionne en mode strict, ce qui signifie qu'il vous permettra seulement d'enregistrer des données qu'il connaît à l'avance. Comme nous utiliserons le mode strict, nous devrons définir la forme de nos données en utilisant un schéma . Les schémas vous permettent de définir les champs stockés dans chaque document avec leur type, les exigences de validation et les valeurs par défaut.
Pour cela, créez un dossier models
dans la racine du projet, et dans ce dossier, un nouveau fichier nommé Registration.js
.
Ajouter le code suivant à Registration.js
:
const mongoose = require ('mongoose');
const registrationSchema = new mongoose.Schema ({
prénom: {
type: chaîne,
couper: vrai,
},
email: {
type: chaîne,
couper: vrai,
},
});
module.exports = mongoose.model ('Registration', registrationSchema);
Ici, nous ne faisons que définir un type (car nous avons déjà une validation en place) et utilisons la méthode d'aide à la coupe pour supprimer tout espace blanc superflu de l'entrée de l'utilisateur. Nous avons ensuite compiler un modèle à partir de la définition du schéma, et l'exporter pour une utilisation ailleurs dans notre application.
Le dernier morceau de la règle standard est d'exiger le modèle dans start.js
:
...
require ('./ models / Registration');
const app = require ('./ app');
serveur const = app.listen (3000, () => {
console.log (`Express s'exécute sur le port $ {server.address (). port}`);
});
Enregistrer les données dans la base de données
Nous sommes maintenant prêts à enregistrer les données utilisateur dans notre base de données. Commençons par exiger Mongoose et importer notre modèle dans notre fichier routes / index.js
:
const express = require ('express');
const mongoose = require ('mongoose');
const {body, validationResult} = require ('exprès-validateur / contrôle');
routeur const = express.Router ();
const Enregistrement = mongoose.model ('Enregistrement');
...
Maintenant, lorsque l'utilisateur publie des données sur le serveur, si la validation réussit, nous pouvons créer un nouvel objet Registration
et tenter de le sauvegarder. Comme l'opération de base de données est une opération asynchrone qui renvoie une promesse, nous pouvons enchaîner un .then ()
sur la fin de celui-ci pour traiter un insert réussi et un .catch ()
pour gérer les erreurs:
if (errors.isEmpty ()) {
const registration = new Enregistrement (req.body);
registration.save ()
.then (() => {res.send ('Merci pour votre inscription!');})
.catch (() => {res.send ('Désolé, quelque chose s'est mal passé.');});
} autre {
...
}
...
Maintenant, si vous entrez vos coordonnées dans le formulaire d'inscription, elles devraient être conservées dans la base de données. You can check this using Compass (making sure to hit the refresh button in the top left if it’s still running).
Using Compass to check that our data was saved to MongoDB
Retrieve Data from the Database
To round the app off, let’s create a final route, which lists out all of our registrations. Hopefully you should have a reasonable idea of the process by now.
Add a new route to routes/index.js
as follows:
router.get('/registrations', (req, res) => {
res.render('index', { title: 'Listing registrations' });
});
This means that we’ll also need a corresponding view template (views/index.pug
):
extends layout
block content
p No registrations yet :(
Now when you visit http://localhost:3000/registrationsyou should see a message telling you that there aren’t any registrations.
Let’s fix that by retrieving our registrations from the database and passing them to the view. We’ll still display the “No registrations yet” message, but only if there really aren’t any.
In routes/index.js
:
router.get('/registrations', (req, res) => {
Registration.find()
.then((registrations) => {
res.render('index', { title: 'Listing registrations', registrations });
})
.catch(() => { res.send('Sorry! Something went wrong.'); });
});
Here, we’re using Mongo’s Collection#find methodwhich, if invoked without parameters, will return all of the records in the collection. Because the database lookup is asynchronous, we’re waiting for it to complete before rendering the view. If any records were returned, these will be passed to the view template in the registrations
property. If no records were returned registrations
will be an empty array.
In views/index.pug
we can then check the length of whatever we’re handed and either loop over it and output the records to the screen, or display a “No registrations” message:
extends layout
block content
if registrations.length
table
tr
th Name
th Email
each registration in registrations
tr
td= registration.name
td= registration.email
autre
p No registrations yet :(
Add HTTP Authentication
The final feature we’ll add to our app is HTTP authenticationlocking down the list of successful registrations from prying eyes.
To do this, we’ll use the http-auth modulewhich we can install using:
npm install --save http-auth
Next we need to require it in routes/index.js
along with the Path module we met earlier:
const path = require('path');
const auth = require('http-auth');
Next, let it know where to find the file in which we’ll list the users and passwords (in this case users.htpasswd
in the project root):
const basic = auth.basic({
file: path.join(__dirname, '../users.htpasswd'),
});
Create this users.htpasswd
file next and add a username and password separated by a colon. This can be in plain text, but the http-auth module also supports hashed passwords, so you could also run the password through a service such as Htpasswd Generator.
For me, the contents of users.htpasswd
looks like this:
jim:$apr1$FhFmamtz$PgXfrNI95HFCuXIm30Q4V0
This translates to user: jim
password: password
.
Finally, add it to the route you wish to protect and you’re good to go:
router.get('/registrations', auth.connect(basic), (req, res) => {
...
});
Serve Static Assets in Express
Let’s give the app some polish and add some styling using Twitter Bootstrap. We can serve static files such as images, JavaScript files and CSS files in Express using the built-in express.static middleware function.
Setting it up is easy. Just add the following line to app.js
:
app.use(express.static('public'));
Now we can load files that are in the public directory
.
Style the App with Bootstrap
Create a public
directory in the project root, and in the public
directory create a css
directory. Download the minified version of Bootstrap v4 into this directory, ensuring it’s named bootstrap.min.css
.
Next, we’ll need to add some markup to our pug templates.
In layout.pug
:
doctype html
html
tête
title= `${title}`
link(rel='stylesheet', href='/css/bootstrap.min.css')
link(rel='stylesheet', href='/css/styles.css')
corps
div.container.listing-reg
h1 My Amazing App
block content
Here, we’re including two files from our previously created css
folder and adding a wrapper div.
In form.pug
we add some class names to the error messages and the form elements:
extends layout
block content
-data = data || {}
if errors
ul.my-errors
for error in errors
li= error.msg
form(action="." method="POST" class="form-registration")
label(for="name") Name:
input(
type="text"
id="name"
name="name"
class="form-control"
value=data.name
)
label(for="email") Email:
input(
type="email"
id="email"
name="email"
class="form-control"
value=data.email
)
input(
type="submit"
value="Submit"
class="btn btn-lg btn-primary btn-block"
)
And in index.pug
more of the same:
extends layout
block content
if registrations.length
table.listing-table.table-dark.table-striped
tr
th Name
th Email
each registration in registrations
tr
td= registration.name
td= registration.email
autre
p No registrations yet :(
Finally, create a file called styles.css
in the css
folder and add the following:
body {
padding: 40px 10px;
background-color: #eee;
}
.listing-reg h1 {
text-align: centre;
margin: 0 0 2rem;
}
/* css for registration form and errors*/
.form-registration {
max-width: 330px;
padding: 15px;
margin: 0 auto;
}
.form-registration {
display: flex;
flex-wrap: wrap;
}
.form-registration input {
width: 100%;
margin: 0px 0 10px;
}
.form-registration .btn {
flex: 1 0 100%;
}
.my-errors {
margin: 0 auto;
padding: 0;
list-style: none;
color: #333;
font-size: 1.2rem;
display: table;
}
.my-errors li {
margin: 0 0 1rem;
}
.my-errors li:before {
content: "! Error : ";
color: #f00;
font-weight: bold;
}
/* Styles for listing table */
.listing-table {
width: 100%;
}
.listing-table th,
.listing-table td {
rembourrage: 10px;
border-bottom: 1px solid #666;
}
.listing-table th {
background: #000;
color: #fff;
}
.listing-table td:first-child,
.listing-table th:first-child {
border-right: 1px solid #666;
}
Now when you refresh the page, you should see all of the Bootstrap glory!
Conclusion
I hope you’ve enjoyed this tutorial. While we didn’t build the next Facebook, I hope that I was nonetheless able to help you get your feet wet in the world of Node-based web apps and offer you some solid takeaways for your next project in the process.
Of course it’s hard to cover everything in one tutorial and there are lots of ways you could elaborate on what we’ve built here. For example, you could check out our article on deploying Node apps and try your hand at launching it to Heroku or now. Alternatively, you might augment the CRUD functionality with the ability to delete registrations, or even write a couple of tests to test the app’s functionality.
Wherever you go from here, I’d be glad to hear any questions or comments below.
Source link