Construire des applications Web en utilisant Node.js

introduction

Outre la construction d’API, Node.js est idéal pour la création d’applications Web standard. Il dispose d'outils puissants pour répondre aux goûts des développeurs Web. Dans ce tutoriel, vous allez créer une application Web pouvant servir de bibliothèque locale.. 

Pendant la construction, vous en apprendrez sur certains types de middleware, vous verrez comment gérer la soumission des formulaires dans Node.js, et vous pourrez également référencer deux modèles..

Commençons.

Commencer

Commencez par installer le générateur express sur votre machine.

npm installer express-generator -g

Exécutez la commande express generator pour générer votre application..

express tutsplus-library --view = pug
 créer: tutsplus-bibliothèque créer: tutsplus-bibliothèque / package.json créer: tutsplus-bibliothèque / app.js créer: tutsplus-bibliothèque / public créer: tutsplus-bibliothèque / routes créer: tutsplus-bibliothèque / routes / index.js créer: tutsplus-library / routes / users.js créer: tutsplus-library / views créer: tutsplus-library / views / index.pug créer: tutsplus-library / views / layout.pug créer: tutsplus-library / views / error.pug créer : bibliothèque tutsplus / bin créer: bibliothèque tutsplus / bin / www créer: bibliothèque tutsplus / public / javascripts créer: bibliothèque tutsplus / public / images créer: bibliothèque tutsplus / public / stylesheets créer: bibliothèque tutsplus / public / dépendances d'installation de stylesheets / style.css: $ cd tutsplus-library && npm install exécutez l'application: $ DEBUG = tutsplus-library: * npm start

Maintenant migrez dans votre travail, ouvrez package.json, et rendez les dépendances similaires à celles que j'ai ci-dessous.

# package.json "name": "tutsplus-library", "version": "0.0.0", "private": true, "scripts": "start": "node ./bin/www", "dépendances": "analyseur de corps": "~ 1.17.1", "connect-flash": "^ 0.1.1", "analyseur de cookie": "~ 1.4.3", "debug": "~ 2.6.3 "," express ":" ~ 4.15.2 "," messages express ":" ^ 1.0.1 "," express-session ":" ^ 1.15.5 "," express-validator ":" ^ 4.2.1 "," mangouste ":" ^ 4.11.12 "," morgan ":" ~ 1.8.1 "," pug ":" ~ 2.0.0-beta11 "," serve-favicon ":" ~ 2.4. 2 "

Exécutez la commande pour installer les packages.

npm installer

Configurer le fichier d'entrée

app.js a été créé lorsque vous avez exécuté la commande du générateur; Cependant, vous devez configurer une configuration supplémentaire. Editez le fichier pour qu'il ressemble à ce que j'ai ci-dessous.

# app.js var express = require ('express'); var path = require ('path'); var favicon = require ('serve-favicon'); var logger = require ('morgan'); var cookieParser = require ('cookie-parser'); var bodyParser = require ('analyseur de corps'); const session = require ('express-session') const const ExpressValidator = require ('express-validator') const flash = require ('connect-flash') const mongoose = require ('mongoose') // 1 const genres = require ( './routes/genres'); const books = require ('./ routes / books'); var app = express (); // 2 mongoose.Promise = global.Promise const mongoDB = process.env.MONGODB_URI || 'mongodb: //127.0.0.1/tutsplus-library' mongoose.connect (mongoDB) // configuration du moteur de visualisation app.set ('views', path.join (__ nomrépertoire, 'views')); app.set ('view engine', 'pug'); // décommentez votre commentaire après avoir placé votre favicon dans / public //app.use(favicon(path.join(__dirname, 'public', 'favicon.ico'))); app.use (enregistreur ('dev')); app.use (bodyParser.json ()); app.use (bodyParser.urlencoded (extended: false)); app.use (cookieParser ()); app.use (express.static (path.join (__ nom de répertoire, 'public'))); // 3 app.use (session (secret: 'secret', saveUninitialized: true, resave: true)) // 4 app.use (expressValidator (errorFormatter: function (param, msg, value) var namespace = param.split ('.'), root = namespace.shift (), formParam = root while (namespace.length) formParam + = '[' + namespace.shift () + '' ' retour param: formParam, msg: msg, valeur: valeur)) // 5 app.use (flash ()) app.use (fonction (req, res, suivante) res.locals.messages = require ('messages express') next ()) // 6 app.use ('/ genres', genres); app.use ('/ livres', livres); // intercepte 404 et le transmet au gestionnaire d'erreurs app.use (function (req, res, next) var err = new Erreur ('Not Found'); err.status = 404; next (err);); // gestionnaire d'erreur app.use (function (err, req, res, next) // définir les paramètres locaux, fournissant uniquement une erreur de développement res.locals.message = err.message; res.locals.error = req.app.get ('env') === 'développement'? err: ; // restitue la page d'erreur res.status (err.status || 500); res.render ('error');); module.exports = app;
  1. Vous aviez besoin des deux routes que vous utiliserez pour créer cette application. Vous allez créer le fichier de routes sous peu. Les itinéraires requis sont affectés en tant que valeurs à deux variables différentes qui sont utilisées lors de la configuration du middleware pour vos itinéraires..
  2. Vous définissez Mongoose à utiliser global.Promise. La variable MongoDB est assigné le MONGODB_URI de votre environnement ou du chemin d'accès à votre serveur Mongo local. Cette variable est transmise en tant qu'argument pour se connecter au serveur MongoDB en cours d'exécution..
  3. Vous configurez un middleware de session à l'aide de session express. Ce middleware est important car vous allez afficher des messages flash dans certaines parties de votre application..
  4. Vous configurez le middleware pour la validation. Ce middleware sera utilisé pour valider la saisie du formulaire, en s'assurant que les utilisateurs de l'application ne soumettent pas de formulaire vide. La validation utilise un package installé, validateur express.
  5. Vous configurez un middleware qui vous sera utile lors de l'affichage de messages flash. Ce middleware utilise connecter flash.
  6. Les routes de l'application sont configurées pour utiliser le fichier de routes requis. Demandes pointant vers / genres et /livres utilisera respectivement les fichiers de genres et de routes de livres. Pour l'instant, vous n'avez pas créé les fichiers de routes, mais vous le ferez bientôt.

Modèle de livre et genre

Le modèle de livre utilisera le schéma Mongoose pour définir la structure des livres. Créez un répertoire appelé des modèles, et un nouveau fichier appelé Book.js. Voici à quoi cela ressemble.

# modèles / Book.js const mongoose = require ('mongoose') mongoose.Promise = global.Promise const Schema = mongoose.Schema const bookSchema = Schema (nom: type: Chaîne, trim: true, requis: 'Veuillez entrer un nom de livre ', description: type: String, trim: true, auteur: type: String, trim: true,, genre: [type: Schema.Types.ObjectId, ref:' Genre '] ) module.exports = mongoose.model ('Livre', bookSchema)

Ici vous avez quatre champs. Le dernier champ est utilisé pour stocker le genre auquel chaque livre appartient. Le champ genre fait ici référence au modèle Genre, qui sera créé ensuite. C'est pourquoi le type est défini sur Schema.Types.ObjectId, qui est où les identifiants de chaque genre référencé seront sauvegardés. ref spécifie le modèle que vous référencez. Notez que le genre est enregistré sous forme de tableau, ce qui signifie qu'un livre peut avoir plus d'un genre..

Allons de l'avant pour créer le modèle Genre.

# models / genre.js const mongoose = require ('mongoose') mongoose.Promise = global.Promise const Schema = mongoose.Schema const genreSchema = Schema (nom: type: String, trim: true, requis: 'Veuillez entrer un nom de genre ') module.exports = mongoose.model (' Genre ', genreSchema)

Pour votre genre, vous n'avez besoin que d'un seul champ: prénom.

Index de genre Route et vue

Pour ce tutoriel, vous utiliserez deux chemins d’itinéraires pour votre genre: un chemin pour ajouter de nouveaux genres et un autre qui répertorie les genres que vous avez. Créez un fichier dans votre répertoire de routes appelé genres.js.

Commencez par demander tous les modules que vous utiliserez..

# routes / genres.js var express = require ('express'); var routeur = express.Router (); const mangouste = require ('mangouste') const Genre = require ('… / models / Genre')

Ensuite, déposez la route qui gère le fichier d'index pour vos genres.

router.get ('/', (req, res, next) => const genres = Genre.find (). exec () .then ((genres) => res.render ('genres', , genres: genres), (err) => throw err));

Cette route est appelée chaque fois que des demandes sont faites à / genres. Ici, vous appelez la méthode find sur votre modèle Genre pour obtenir tous les genres créés. Ces genres sont ensuite rendus sur un modèle appelé genres. Continuons et créons cela, mais d’abord, mettez à jour votre layout.pug ressembler à ceci:

# views / layout.pug doctype html html head titre = titre link (rel = 'stylesheet', href = "/ stylesheets / style.css") lien (rel = 'stylesheet', href = "https://bootswatch.com /paper/bootstrap.css ") script (src = 'https: //ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js') script (src = 'https: // maxcdn .bootstrapcdn.com / bootstrap / 3.3.7 / js / bootstrap.min.js ') body. entête du bloc .container-fluid nav.navbar.navbar-inverse .container-fluid .navbar-header button.navbar-toggle.collapsed ( type = 'bouton', data-toggle = "collapse", data-target = "# bs-example-navbar-collapse-2") span.sr-only Basculer la navigation span.icon-bar span.icon-bar span. icon-bar a.navbar-brand (href = '#') Bibliothèque locale # bs-example-navbar-collapse-2.collapse.navbar-collapse ul.nav.navbar-nav.navbar-right li a (href = ' / books ') Afficher les livres li a (href =' / books / add ') Ajouter un nouveau livre li a (href =' / genres ') Afficher les genres li a (href =' / genres / add ') Ajouter un nouveau contenu de bloc de genre

Cela donnera à vos vues une belle structure pour faciliter la navigation. Maintenant, créez un fichier de vue appelé genre.pug. Dans ce fichier, vous allez parcourir les genres créés et afficher chaque genre dans une liste non ordonnée..

Voici à quoi devrait ressembler le fichier.

# views / genres.pug étend le contenu du bloc de disposition h1 Genre ul.well.well-lg chaque genre, i dans les genres li.well.well-sm p # genre.name

Ajouter de nouvelles routes de genre et une vue

Retournez à votre itinéraires / genres.js ajouter les itinéraires qui gèrent la création de nouveaux genres.

# routes / genres.js // 1 router.get ('/ add', (req, res, next) => res.render ('addGenre')) // 2 router.post ('/ add', (req, res, next) => req.checkBody ('name', 'Name is required'). notEmpty () const errors = req.validationErrors () if (erreurs) console.log (erreurs) res.render ('addgenres', genre, erreurs) const genre = (nouveau genre (req.body)). save () .then ((data) => res.redirect ('/ genres')) .catch ((errors) => console.log ('oops…') console.log (erreurs))) // 3 module.exports = router;
  1. Le travail de ce routeur consiste simplement à afficher la page permettant d’ajouter de nouvelles routes. Ce routeur est appelé chaque fois que des demandes sont faites à / genres / ajouter chemin.
  2. Ce routeur gère la soumission du formulaire. Lorsque le formulaire est soumis, nous vérifions que le nom est bien saisi par l'utilisateur. Si aucun nom n'est entré, la page est rendue à nouveau. Si les vérifications sont bonnes, le genre est enregistré et l’utilisateur est redirigé vers le / genres page.
  3. Le module est exporté en tant que routeur.

Maintenant, vous pouvez continuer et créer la page pour ajouter un nouveau genre.

# views / addGenre.pug étend le contenu du bloc de disposition .row .col-md-12 h1 Formulaire Ajouter un livre (method = "POST", action = "/ genres / add") .form-group label.col-lg-2. control.label Nom .col-lg-10 input.form-control (type = "texte", nom = "nom"). groupe-de-formes .col-lg-10.col-lg-offset-2 input.button. btn.btn-primary (type = 'submit', valeur = "Submit") si errors ul pour erreur dans les erreurs li! = error.msg

Livres Routes and View

Créez un nouveau fichier de route pour les livres et nommez-le. books.js. Comme vous l'avez fait précédemment avec le genre, commencez par demander les modules nécessaires.

# routes / books.js var express = require ('express'); var routeur = express.Router (); const mongoose = require ('mongoose') const Livre = require ('… / models / Book') const Genre = require ('… / models / Genre')

Ensuite, configurez le routeur pour afficher tous les livres enregistrés dans la bibliothèque. Essayez-le vous-même de la même manière que vous définissez celui du genre; vous pouvez toujours vérifier pour apporter des corrections.

Je suppose que vous avez essayé cela, voici à quoi cela devrait ressembler.

router.get ('/', (req, res, next) => const books = Book.find (). exec (). then ((books) => res.render ('livres', , livres: livres), (err) => throw err));

Lorsque ce routeur est appelé, une demande est faite pour trouver tous les livres enregistrés dans la base de données. Si tout va bien, les livres sont affichés sur le /livres page, sinon une erreur est renvoyée.

Vous devez créer un nouveau fichier pour afficher tous les livres. Voici à quoi il devrait ressembler..

# views / books.pug étend le contenu du bloc de disposition h1 Livres ul.well.well-lg chaque livre, i dans les livres li.well.well-sm a (href = '/ books / show / $ book.id') # book.name p = book.description

Il vous suffit de parcourir les livres retournés et d'afficher le nom et la description de chaque livre à l'aide d'une liste non ordonnée. Le nom du livre pointe vers la page individuelle du livre..

Ajouter les nouvelles routes du livre et la vue

Le prochain routeur que vous configurerez gérera l'ajout de nouveaux livres. Deux routeurs seront utilisés ici: l'un rendra simplement le rendu de la page et un autre gérera la soumission du formulaire..

Voici à quoi ressemblent les routeurs.

router.get ('/ add', (req, res, next) => const genres = Genre.find (). exec () .then ((genres) => res.render ('addBooks', genres)) .catch ((err) => jeter err)) router.post ('/ add', (req, res, next) => req.checkBody ('nom', 'nom est requis '). notEmpty () req.checkBody (' description ',' Description obligatoire '). notEmpty () req.checkBody (' genre ',' Genre requis '). notEmpty erreurs constantes = req.validationErrors () if (erreurs) console.log (erreurs) res.render ('addBooks', book, errors) const book = (new Book (req.body)). save () .then ((data) => res.redirect ('/ books')) .catch ((errors) => console.log ('oops…')))

Dans le premier routeur, vous affichez le / addBooks page. Ce routeur est appelé lorsqu’une demande est faite à /ajouter chemin. Comme les livres ajoutés sont supposés avoir des genres, vous voulez afficher les genres qui ont été enregistrés dans la base de données..

 const genres = Genre.find (). exec () .then ((genres) => 

Le code ci-dessus trouve tous les genres de votre base de données et les renvoie dans les genres variables. Avec cela, vous pourrez parcourir les genres et les afficher sous forme de cases à cocher.

Le second routeur gère la soumission du formulaire. Tout d'abord, vous vérifiez le corps de la demande pour vous assurer que certains champs ne sont pas vides. C'est là que le validateur express middleware que vous avez défini app.js est pratique. S'il y a des erreurs, la page est rendue à nouveau. S'il n'y en a pas, la nouvelle instance de livre est enregistrée et l'utilisateur est redirigé vers la page / books.

Allons-y et créons les vues pour cela.

Créer un nouveau fichier de vue appelé addBooks.pug. Notez que le nom de la vue correspond au premier paramètre donné à res.render. C'est parce que vous rendez un modèle. Pendant la redirection, il vous suffit de passer le chemin vers lequel vous souhaitez rediriger, comme vous le faisiez avec res.redirect ('/ books').

Après avoir établi cela, voici à quoi devraient ressembler les vues.

# views / addBooks.pug étend le contenu du bloc de disposition .row .col-md-12 h1 Formulaire Ajouter un livre (method = "POST", action = "/ books / add") .form-group label.col-lg-2. Nom de l'étiquette de contrôle .col-lg-10 input.form-control (type = "texte", nom = "nom") .form-group label.col-lg-2.control-label Auteur .col-lg-10 input.form-control (type = "text", nom = "auteur") .form-group label.col-lg-2.control-label Description du livre .col-lg-10 textarea # textArea.form-control (lignes = '3', nom = "description") .form-group label.col-lg-2.control-label Genre .col-lg-10 pour le genre dans le genre .checkbox input.checkbox (type = 'checkbox', nom = "genre", id = genre._id, valeur = genre._id, coché = genre.checked) étiquette (pour = genre._id) # genre.nom .form-group .col-lg-10.col- lg-offset-2 input.button.btn.btn-primary (type = 'submit', value = "Submit") si errors ul pour erreur dans les erreurs li! = error.msg 

La chose importante à noter ici est l'action et la méthode du formulaire. Lorsque vous cliquez sur le bouton d'envoi, vous effectuez une POSTER demande à / livres / ajouter. Une autre chose: encore une fois, vous parcourez la collection de genres renvoyés et affichez chacun d'eux..

Livre spectacle route et vue

Laissons-nous dans la route pour gérer les demandes faites à chaque page de livres. Pendant que vous y êtes, il est important d’exporter votre module également..

# routes / books.js router.get ('/ show /: id', (req, res, suivant) => const book = Book.findById (_id: req.params.id) .populate (chemin : 'genre', modèle: 'Genre', peupler: chemin: 'genre', modèle: 'Livre') .exec () .then ((livre) => res.render ('livre',  book)) .catch ((err) => jeter err)) module.exports = routeur;

Aucune magie ne se passe ici.

Tout d'abord, les demandes adressées à ce routeur doivent avoir un identifiant: l'identifiant du livre. Cet identifiant est obtenu à partir des paramètres de la requête en utilisant req.params.id. Ceci est utilisé pour identifier le livre spécifique qui devrait être obtenu à partir de la base de données, car les identifiants sont uniques. Lorsque le livre est trouvé, la valeur de genre du livre est renseignée avec tous les genres qui ont été enregistrés dans cette instance de livre. Si tout se passe bien, la vue du livre est rendue, sinon une erreur est générée.

Créons la vue pour un livre. Voici à quoi cela devrait ressembler.

bloquer le contenu .well.well-lg h1 # [nom fort:] # book.name ul li # [description forte:] # book.description li # [auteur fort]: # book.author li # [genre fort:] chaque genre dans book.genre # genre.name |,

Vous pouvez démarrer votre serveur de noeud en lançant:

DEBUG = tutsplus-library: * npm start

Conclusion

Vous savez maintenant comment créer une application Web standard dans Node.js, et pas seulement une application simple à faire. Vous avez pu gérer la soumission de formulaire, référencer deux modèles et configurer un middleware..

Vous pouvez aller plus loin en développant l'application. Essayez d'ajouter la possibilité de supprimer un livre. Tout d’abord, ajoutez un bouton à la page d’affichage, puis accédez aux fichiers de routes et ajoutez un routeur à cet effet. Notez que cela va être un POSTER demande.

Vous pouvez également penser à plus de fonctionnalités à ajouter à l'application. J'espère que tu as aimé.