Serveur rapide Express js. Bases de Node JS & Express (III). Création d'un formulaire HTML et récupération de données

En regardant le modèle de syntaxe, si nous voulions ajouter une nouvelle route à l'application, nous pourrions simplement faire quelque chose comme ce qui suit :

Router.get("/app", function(req, res) ( res.render("app", ( titre : "Express" )); ));

Est-ce l'itinéraire ? Est-ce un contrôleur ?

Le plus intéressant est qu’une route est une fonction contenant de la logique. À l’intérieur de la route se trouve la fonction res.render :

Res.render("foo", ( titre : "Express" ));

Dans le modèle de vue, nous voyons ceci :

H1= titre p Bienvenue dans #(titre)

Ce sont deux exemples de la façon dont nous pouvons extraire des données du contrôleur/route et les afficher dans une vue. Dans cet exemple, nous produisons du HTML :

Exprimer

Bienvenue chez Express

Tout cela semble provenir du problème : une route peut-elle également contenir des informations sur le contrôleur ? C'est vrai, c'est pourquoi il y a un mouvement dans la communauté pour changer le nom du dossier de routes en contrôleurs.

Un bon exemple de ceci peut être vu dans l’exemple Express MVC.

Mais par souci de cohérence, nous nous en tiendrons aux conventions en vigueur dans ce guide.

404 erreurs

Des erreurs vous envoient déjà vers Express. Le fichier app.js contient les éléments suivants :

/// attrape 404 et redirige vers le gestionnaire d'erreurs app.use(function(req, res, next) ( var err = new Error("Not found"); err.status = 404; next(err); ));

Il y a des erreurs.jade dans le dossier vues/.

Étend le contenu du bloc de mise en page h1= message h2= error.status pre #(error.stack)

C'est simple. Si vous souhaitez personnaliser votre page 404, modifiez simplement cette vue.

Cet article est destiné aux développeurs débutants et à toute personne intéressée à travailler avec Node js Express. Pour maîtriser cela, vous devez connaître les bases de JavaScript :

Qu’est-ce que Node.js ?

Node.js est un environnement d'exécution JavaScript asynchrone basé sur le moteur JavaScript V8 de Chrome. Il est conçu pour créer des applications réseau évolutives.

Node.js vous permet d'écrire du code JavaScript côté serveur. Maintenant, vous vous demandez peut-être comment ? JavaScript est un langage qui s'exécute dans le navigateur. Le navigateur accepte le code JavaScript et le compile en commandes. Le créateur de Node.js a pris le moteur Chrome et a construit un runtime ( Durée) pour que cela fonctionne sur le serveur. C'est le support dans lequel le langage peut être interprété. Alors qu’avons-nous maintenant ? Une façon d'écrire du JavaScript dans le backend.

Quant à la définition, vous vous demandez peut-être ce que signifie le terme « asynchrone » dans ce contexte. JavaScript est un langage à thread unique. Par conséquent, vous ne voulez pas que les événements interrompent le thread principal d’exécution. Cela signifie traiter les événements sans interrompre le thread principal.

Node.js est basé sur cette conception non bloquante, ce qui en fait l'un des outils les plus rapides pour créer des applications Web. Dans l'exemple « Hello World » suivant, de nombreuses connexions peuvent être traitées simultanément. Chaque connexion déclenche un rappel.

Cet exemple Node js Express comporte six étapes simples.

  1. Installez Node.js pour votre plateforme (MacOS, Windows ou Linux)

Noeud.js

Node.js® est un runtime JavaScript intégré au moteur JavaScript V8 pour Chrome. Node.js utilise des E/S non bloquantes et pilotées par les événements...

La première étape consiste à obtenir une instance de JavaScript sur votre ordinateur local. Tapez nodejs.org dans la barre d'adresse de votre navigateur ou cliquez sur le lien et vous avez terminé. La fenêtre de lancement devrait vous donner immédiatement ce que vous voulez. Lorsque je lance Ubuntu sur mon ordinateur, la version correspondante de Node.js pour mon système d'exploitation s'affiche. Téléchargez-le et installez-le. Cela vous fournira les outils dont vous avez besoin pour exécuter le serveur sur votre ordinateur local :

  1. Ouvrez une invite de commande et tapez

mkdir monapplication cd monapplication

Ces commandes Node js Express Post sont universelles pour tout système d'exploitation. Le premier créera un nouveau répertoire dans le répertoire dans lequel vous vous trouvez actuellement, mkdir = "make directory" . Ce dernier passera à ce répertoire nouvellement créé, cd = "change directory" .

  1. Exécutez votre projet et liez-le à npm

Après avoir créé un répertoire appelé myapp, vous devrez exécuter le projet et le lier à npm.

Npm est l'abréviation de gestionnaire de packages de nœuds ( Gestionnaire de packages de nœuds). C'est ici que se trouvent tous les packages Node. Ils peuvent être considérés comme des packages de code, des modules qui remplissent une fonction spécifique. Nous utilisons l'interface du programme d'application, API, fournie par ces modules.

Les modules, à leur tour, agissent comme des boîtes noires avec des boutons et des leviers qui peuvent être poussés et tirés pour obtenir le résultat souhaité. L'exécution de la commande ci-dessous démarre votre projet :

Il crée un fichier package.json dans le dossier myapp. Le fichier contient des liens vers tous les packages npm chargés dans le projet.

La commande vous demandera de saisir plusieurs options d'action. Vous pouvez entrer votre chemin à travers chacun d’eux sauf celui-ci :

point d'entrée : (index.js)

Vous voudrez changer cela en :

  1. Installer Express dans le répertoire myapp

Express est un framework d'application Web Node.js minimal et flexible qui fournit un ensemble robuste de fonctionnalités pour le Web.

Dans le répertoire myapp, exécutez :

npm install express --save

La commande d'installation continuera à rechercher le package de fichiers Node js Express à installer. Installez-le dans votre projet.

Un dossier node_modules est désormais créé à la racine de votre projet. L'ajout de -save permet d'enregistrer le package dans la liste de dépendances située dans package.json dans le répertoire myapp.

Express fournit un ensemble d'outils pour créer et exécuter une application Web. Express est devenu si populaire qu'il est désormais standard dans la grande majorité des applications Node.js. Je recommande fortement d'utiliser Express.

  1. Lancez un éditeur de texte et créez un fichier appelé app.js

Après avoir installé Express Node, ajoutez le code suivant au fichier créé :

var express = require("express"); var app = express(); app.get("/", function (req, res) ( res.send("Hello World!"); )); app.listen(3000, function() ( console.log("Exemple d'application écoutant sur le port 3000 !"); ));

Ici, vous devrez utiliser un package récemment installé. La première ligne déclare une variable qui contiendra le module express, situé dans le dossier node_modules.

Un module est une fonction. L'attribution d'un appel de fonction à une autre variable donne accès à un ensemble d'outils prédéfinis qui facilitent le travail futur. Vous pouvez considérer une application temporaire comme un objet dont vous utilisez les méthodes pour créer le programme réel.

La méthode d'écoute démarre le serveur et écoute sur le port 3000 les connexions. Il répond « Bonjour tout le monde ! " pour les requêtes GET vers l'URL racine (/). Pour tout autre chemin, il répondra par 404 Not Found.

  1. Lancez l'application

Entrez la commande :

Après avoir exécuté la commande, saisissez http://localhost:3000/ dans votre navigateur pour voir le résultat. Vous devriez également voir " Exemple d'application écoutant sur le port 3000».

$ npm installer express

ou, pour avoir accès à la commande express, installez globalement :

$ npm install -g express

Départ rapide

Le moyen le plus simple de démarrer avec Express est d'exécuter la commande express, qui générera l'application :

Création d'une application :

$ npm install -g express $ express /tmp/foo && cd /tmp/foo

Installation des dépendances :

$ npm installer -d

Démarrage du serveur :

Création d'un serveur

Pour créer une instance de express.HTTPServer, appelez simplement la méthode createServer(). Avec notre instance d'application, nous pouvons spécifier des routes basées sur des méthodes HTTP, dans cet exemple app.get() .

var app = require("express").createServer(); app.get("/", function(req, res)( res.send("hello world"); )); app.écouter (3000);

Création d'un serveur HTTPS

Pour initialiser express.HTTPSServer , nous effectuons les mêmes étapes que ci-dessus, mais nous transmettons également un objet options contenant la clé, le certificat et d'autres paramètres décrits dans la documentation du module https NodeJS.

var app = require("express").createServer(( clé : ... ));

Configuration

Express prend en charge les environnements arbitraires, tels que la production et le développement. Les développeurs peuvent utiliser la méthode configure() pour ajouter les fonctionnalités nécessaires à un environnement donné. Lorsque configure() est appelé sans nom d'environnement, il se déclenchera dans n'importe quel environnement avant que toute configuration dans laquelle l'environnement est spécifié ne se déclenchera.

Dans l'exemple ci-dessous, nous utilisons simplement l'option dumpExceptions et, en mode développement, répondons au client avec une trace de pile de l'exception. Dans les deux modes, nous utilisons les couches methodOverride et bodyParser. Notez l'utilisation de app.router , qui lui-même permet de monter les routes - sinon elles sont montées la première fois que app.get() , app.post() , etc. sont appelées.

app.configure(function())( app.use(express.methodOverride()); app.use(express.bodyParser()); app.use(app.router); )); app.configure("development", function())( app.use(express.static(__dirname + "/public")); app.use(express.errorHandler(( dumpExceptions: true, showStack: true ))); ) ); app.configure("production", function())( var oneYear = 31557600000; app.use(express.static(__dirname + "/public", ( maxAge: oneYear ))); app.use(express.errorHandler() ) ; ));

Pour les environnements avec des paramètres similaires, vous pouvez transmettre plusieurs noms d'environnement :

app.configure("stage", "prod", function())( // config ));

Pour les paramètres internes et arbitraires, Express a les méthodes set(key[, val]) , enable(key) , Disable(key) :

app.configure(function () ( app.set("views", __dirname + "/views"); app.set("views"); // => "/absolute/path/to/views" app.enable ("une fonctionnalité"); // identique à app.set("une fonctionnalité", true); app.disable("une fonctionnalité"); // identique à app.set("une fonctionnalité", false) ; app .enabled("une fonctionnalité") // => false ));

Pour définir l'environnement, nous pouvons définir la variable d'environnement NODE_ENV. Par exemple:

$ NODE_ENV=nœud de production app.js

Ceci est très important car de nombreux mécanismes de mise en cache ne sont activés que dans un environnement de production.

Paramètres

Prêt à l'emploi, Express prend en charge les paramètres suivants :

  • home est le chemin de base de l'application, qui est utilisé pour res.redirect() ainsi que pour la prise en charge transparente des applications montées.
  • vues est le répertoire racine des vues. Par défaut dossier_actuel/vues
  • moteur de vue - moteur de modèle par défaut pour les vues appelées sans extension de fichier.
  • options d'affichage - un objet reflétant les options d'affichage globales
  • view cache - activer la mise en cache des vues (activé dans l'environnement de production)
  • routes sensibles à la casse - activer les routes sensibles à la casse
  • routage strict - si activé, les barres obliques finales ne sont plus ignorées
  • jsonp callback - autoriser la méthode res.send() à prendre en charge de manière transparente JSONP

Routage

Express utilise des méthodes HTTP pour fournir une API de routage significative et expressive. Par exemple, nous souhaitons que la recherche de /user/12 affiche le profil de l'utilisateur avec id=12 . Pour ce faire, nous définissons l'itinéraire ci-dessous. Les valeurs associées aux champs nommés sont disponibles dans l'objet res.params.

app.get("/user/:id", function(req, res)( res.send("user " + req.params.id); ));

Une route est simplement une chaîne compilée dans une expression régulière à l’intérieur du moteur. Par exemple, lorsque /user/:id est compilé, le résultat est une expression régulière comme celle-ci :

\/utilisateur\/([^\/]+)\/?

Vous pouvez également transmettre immédiatement une expression régulière. Mais comme les groupes ne sont pas nommés dans les expressions régulières, ils peuvent être atteints dans req.params par des nombres. Ainsi, le premier groupe va dans req.params , le second dans req.params , etc.

app.get(/^\/users?(?:\/(\d+)(?:\.\.(\d+))??/, function(req, res)( res.send(req.params ); ));

Prenons maintenant curl et envoyons une requête à la route ci-dessus :

$ curl http://dev:3000/user $ curl http://dev:3000/users $ curl http://dev:3000/users/1 ["1",null] $ curl http://dev : 3000/utilisateurs/1..15 ["1","15"]

Vous trouverez ci-dessous quelques exemples d'itinéraires et de chemins qui pourraient y correspondre :

"/user/:id" /user/12 "/users/:id?" /users/5 /users "/files/*" /files/jquery.js /files/javascripts/jquery.js "/file/*.*" /files/jquery.js /files/javascripts/jquery.js "/ utilisateur/:id/:opération?" /user/1 /user/1/edit "/products.:format" /products.json /products.xml "/products.:format?" /products.json /products.xml /products "/user/:id.:format?" /user/12 /user/12.json

Par exemple, nous pouvons POST du JSON et répondre avec le même JSON en utilisant la couche bodyParser, qui peut analyser une requête JSON (ainsi que d'autres requêtes) et placer la réponse dans req.body :

var express = require("express"), app = express.createServer(); app.use(express.bodyParser()); app.post("/", function(req, res) ( res.send(req.body); )); app.écouter (3000);

En règle générale, nous utilisons un champ « stupide » (par exemple, /user/:id), qui n'a aucune restriction. Mais si nous voulons, par exemple, limiter l’ID utilisateur aux seuls caractères numériques, nous pouvons utiliser /user/:id(+) . Cette conception ne fonctionnera pas si la valeur du champ contient des caractères non numériques.

Transférer le contrôle vers un autre itinéraire

En appelant le troisième argument, next() , vous pouvez passer le contrôle de la route suivante. Si aucune correspondance n'est trouvée, le contrôle est rendu à Connect et les couches continuent d'être appelées dans l'ordre dans lequel elles ont été activées à l'aide de use() . Plusieurs itinéraires partageant le même chemin fonctionnent également. Ils sont simplement appelés un par un jusqu'à ce que l'un d'eux réponde au lieu d'appeler next() .

app.get("/users/:id?", function(req, res, next) ( var id = req.params.id; if (id) ( // faire quelque chose ) else ( next(); ) )) ; app.get("/users", function(req, res) ( // faire autre chose ));

La méthode app.all() est utile si vous souhaitez appliquer la même logique pour toutes les méthodes HTTP. Ci-dessous, nous utilisons cette méthode pour récupérer un utilisateur de la base de données et l'attribuer à req.user.

var express = require("express"), app = express.createServer(); var utilisateurs = [( nom : "tj" )]; app.all("/user/:id/:op?", function(req, res, next) ( req.user = users; if (req.user) ( next(); ) else ( next(new Error( "utilisateur introuvable" + req.params.id)); ) )); app.get("/user/:id", function(req, res) ( res.send("viewing " + req.user.name); )); app.get("/user/:id/edit", function(req, res) ( res.send("editing " + req.user.name); )); app.put("/user/:id", function(req, res) ( res.send("updating " + req.user.name); )); app.get("*", function(req, res) ( res.send("quoi???", 404); )); app.écouter (3000);

Intercalaires

Les couches du framework Connect peuvent être transmises à express.createServer() de la même manière que si un serveur Connect standard était utilisé. Par exemple:

var express = require("express"); var app = express.createServer(express.logger(), express.bodyParser());

Vous pouvez également utiliser use() . Cela rend plus pratique l’ajout de couches à l’intérieur des blocs configure(), ce qui est plus progressif.

app.use(express.logger(( format: ":method:url" )));

Généralement, avec les couches Connect, nous pouvons connecter Connect comme ceci :

var connect = require("connecter"); app.use(connect.logger()); app.use(connect.bodyParser());

Ce n'est pas tout à fait pratique, donc Express réexporte les couches Connect :

app.use(express.logger()); app.use(express.bodyParser());

L'ordre des couches est important. Ainsi, lorsque Connect reçoit une requête, la première couche ajoutée via createServer() ou use() est exécutée. Il est appelé avec trois paramètres : requête, réponse et une fonction de rappel, généralement appelée next. lorsque next() est appelé, le contrôle est passé à la deuxième couche, etc. Il est important d’en tenir compte, car de nombreuses couches dépendent les unes des autres. Par exemple, methodOverride() appelle req.body.method pour surcharger une méthode HTTP, et bodyParser() analyse le corps de la requête pour remplir req.body . Un autre exemple est l'analyse des cookies et la prise en charge de la session - vous devez d'abord appeler use() sur cookieParser() , puis sur session() .

De nombreuses applications Express peuvent avoir la ligne app.use(app.router) . Cela peut paraître étrange, mais il s'agit simplement de spécifier explicitement la couche qui inclut toutes les routes que nous avons créées. Cette couche peut être incluse dans n'importe quel ordre, bien que par défaut elle soit incluse à la fin. En changeant sa position, vous pouvez contrôler l'ordre de son exécution. Par exemple, nous avons besoin d'un gestionnaire d'erreurs qui se déclenchera après toutes les autres couches et affichera toute exception qui lui est transmise à l'aide de next() . Ou il peut être nécessaire de réduire l'ordre d'exécution de la couche servant les fichiers statiques pour permettre à d'autres routes d'intercepter les demandes concernant ces fichiers et, par exemple, de compter le nombre de téléchargements, etc. Voici à quoi cela pourrait ressembler :

app.use(express.logger(...)); app.use(express.bodyParser(...)); app.use(express.cookieParser(...)); app.use(express.session(...)); app.use(app.router); app.use(express.static(...)); app.use(express.errorHandler(...));

Nous ajoutons d’abord logger() – il encapsulera la méthode req.end() pour nous donner des données sur le taux de réponse. Ensuite, nous analysons le corps de la requête (s'il y en a un), puis les cookies, puis la session, de sorte que req.session soit déjà défini lorsque nous arrivons aux routes dans app.router . Si, par exemple, une requête GET vers /javascripts/jquery.js est gérée par des routes et que nous n'appelons pas next() , alors la couche static() ne recevra jamais cette requête. Cependant, si nous définissons un itinéraire comme indiqué ci-dessous, il sera possible d'enregistrer des statistiques, de refuser des téléchargements, de facturer des téléchargements, etc.

var téléchargements = (); app.use(app.router); app.use(express.static(__dirname + "/public")); app.get("/*", function(req, res, next) ( var file = req.params; downloads = downloads || 0; downloads++; next(); ));

Itinéraires en couches

Les routes peuvent utiliser des couches de routage en transmettant des rappels (ou tableaux) supplémentaires à la méthode. Ceci est utile si vous devez restreindre l'accès ou charger des données avant d'utiliser un itinéraire, etc.

En règle générale, la récupération de données asynchrone peut ressembler à celle illustrée ci-dessous (ici, nous prenons le paramètre :id et chargeons les données utilisateur).

app.get("/user/:id", function(req, res, next) ( loadUser(req.params.id, function(err, user) ( if (err) return next(err); res.send( "Affichage de l'utilisateur" + user.name); )); ));

Pour adhérer au principe DRY et améliorer la lisibilité du code, vous pouvez organiser cette logique à l'aide de couches. Comme vous pouvez le voir, en faisant abstraction de la logique à l'aide de couches, vous pouvez à la fois réaliser la réutilisation des couches et rendre le code de routage plus beau.

function loadUser(req, res, next) ( // ici nous chargeons l'utilisateur depuis la base de données var user = users; if (user) ( req.user = user; next(); ) else ( next(new Error("Failed pour charger l'utilisateur " + req.params.id)); ) ) app.get("/user/:id", loadUser, function(req, res) ( res.send("Viewing user " + req.user.name ) ; ));

Plusieurs couches de routage peuvent être ajoutées et elles seront exécutées séquentiellement pour fournir une logique différente, telle que restreindre l'accès à un compte utilisateur. Dans l'exemple ci-dessous, seul un utilisateur autorisé peut modifier son compte.

function andRestrictToSelf(req, res, next) ( req.authenticatedUser.id == req.user.id ? next() : next(new Error("Unauthorized")); ) app.get("/user/:id/ edit", loadUser, andRestrictToSelf, function(req, res) ( res.send("Modification de l'utilisateur " + req.user.name); ));

Sachant que les calques ne sont que des fonctions, vous pouvez écrire une fonction qui renvoie un calque (pour fournir une solution encore plus expressive et flexible), comme indiqué ci-dessous.

function andRestrictTo(role) ( return function(req, res, next) ( req.authenticatedUser.role == role ? next() : next(new Error("Unauthorized")); ) ) app.del("/user/ :id", loadUser, andRestrictTo("admin"), function(req, res) ( res.send("Utilisateur supprimé " + req.user.name); ));

Les « piles » de couches fréquemment utilisées peuvent être transmises sous forme de tableaux de profondeur et de structure arborescente arbitraires (elles seront appliquées de manière récursive) :

var a = , b = , tous = ; app.get("/foo", a, function() ()); app.get("/bar", a, function() ()); app.get("/", a, middleware3, middleware4, function() ()); app.get("/", a, b, function() ()); app.get("/", all, function() ());

L'exemple complet peut être consulté dans le référentiel.

Il arrive parfois que vous deviez ignorer les couches de routes restantes dans la pile, mais continuer à exécuter les routes suivantes. Pour ce faire, appelez next() avec l'argument route : next("route") . S'il ne reste plus de routes à exécuter, Express répondra par une erreur 404 Not Found.

Méthodes HTTP

Nous avons déjà utilisé app.get() à plusieurs reprises, mais Express fournit également d'autres méthodes HTTP - app.post() , app.del() , etc.

Le cas d’utilisation le plus courant du POST est la soumission d’un formulaire. Dans l'exemple ci-dessous, nous créons simplement un formulaire HTML. Et puis le contrôle sera transféré à l’itinéraire que nous définirons dans l’exemple suivant.

Par défaut, Express ne sait pas quoi faire avec le corps de la requête, nous devons donc ajouter une couche bodyParser() qui analysera le corps de la requête encodé dans application/x-www-form-urlencoded ou application/json et mettra l'analyse aboutit à req .body . Pour ce faire, nous devons dire use() comme ci-dessous :

app.use(express.bodyParser());

Maintenant, la route ci-dessous accédera à l'objet req.body.user, qui aura des propriétés de nom et d'e-mail :

app.post("/", function(req, res) ( console.log(req.body.user); res.redirect("back"); ));

Si le formulaire utilise des méthodes telles que PUT, vous pouvez utiliser une entrée masquée appelée _method, qui vous permet de modifier la méthode HTTP. Pour y parvenir, il faut d'abord activer une couche methodOverride(), qui sera placée après bodyParser(), ce qui lui permettra d'utiliser le req.body contenant les champs du formulaire soumis.

app.use(express.bodyParser()); app.use(express.methodOverride());

Ces couches ne sont pas activées par défaut, car Express ne dispose pas nécessairement de toutes les fonctionnalités immédiatement. Selon les besoins de l'application, vous n'aurez peut-être pas besoin de les utiliser. Et puis les méthodes PUT et DELETE seront toujours disponibles, mais directement. En même temps, methodOverride est une excellente solution pour les formulaires HTML. Vous trouverez ci-dessous un exemple d'utilisation de la méthode PUT :

app.put("/", function() ( console.log(req.body.user); res.redirect("back"); ));

Traitement des erreurs

Express a une méthode app.error() qui accepte toutes les exceptions levées par les routes ou transmises comme next(err) . Vous trouverez ci-dessous un exemple de la manière de servir plusieurs pages à l'aide d'une exception NotFound maison :

function NotFound(msg) ( this.name = "NotFound"; Error.call(this, msg); Error.captureStackTrace(this, arguments.callee); ) NotFound.prototype.__proto__ = Error.prototype; app.get("/404", function(req, res) ( throw new NotFound; )); app.get("/500", function(req, res) ( throw new Error("clavier chat!"); ));

Vous pouvez appeler app.error() plusieurs fois comme indiqué ci-dessous. Ici, nous vérifions l'instance de NotFound et affichons une page 404, ou passons le contrôle au gestionnaire d'erreurs suivant.

Notez que ces gestionnaires peuvent être définis n'importe où, puisqu'ils seront toujours placés sous les gestionnaires de route dans Listen() . Cela permet de les définir dans des blocs configure(), afin que les exceptions puissent être gérées différemment en fonction de l'environnement actuel.

app.error(function(err, req, res, next) ( if (err instanceof NotFound) ( res.render("404.jade"); ) else ( next(err); ) ));

Par souci de simplicité, nous supposons ici que toutes les erreurs ont un code de 500, mais vous pouvez le modifier à votre guise. Par exemple, lorsque Node effectue des opérations sur le système de fichiers, nous pouvons obtenir un objet d'erreur avec un champ error.code = ENOENT, qui signifie « fichier ou répertoire introuvable », nous pouvons l'utiliser dans un gestionnaire d'erreurs et afficher la page correspondante.

app.error(function(err, req, res) ( res.render("500.jade", ( erreur: err )); ));

Les applications peuvent également utiliser la couche errorHander de Connect pour gérer les exceptions. Par exemple, si vous devez afficher les exceptions dans stderr dans l'environnement de développement, vous pouvez procéder comme suit :

app.use(express.errorHandler(( dumpExceptions: true )));

De plus, pendant le développement, nous pouvons avoir besoin de pages HTML sympas qui affichent les exceptions levées ou levées. Dans ce cas, vous devez définir showStack sur true :

app.use(express.errorHandler(( showStack : true, dumpExceptions : true )));

La couche errorHandler répond également en JSON si un en-tête Accept: application/json est passé par le client, ce qui est utile pour développer des applications AJAX.

Paramètres d'itinéraire de prétraitement

Les paramètres d'itinéraire de prétraitement peuvent améliorer considérablement la lisibilité d'une application grâce au chargement explicite des données et à la validation de l'URL de la demande. Par exemple, si vous récupérez constamment des données pour certaines requêtes (par exemple en chargeant des données utilisateur pour /user/:id), vous pouvez faire quelque chose comme ceci :

app.get("/user/:userId", function(req, res, next) ( User.get(req.params.userId, function(err, user) ( if (err) return next(err); res. send("utilisateur " + utilisateur.nom); )); ));

Avec des conditions préalables, nous pouvons attacher des fonctions de rappel à nos paramètres de requête qui effectueraient une validation, restreindraient l'accès ou même chargeraient des données à partir de la base de données. Dans l'exemple ci-dessous, nous appelons app.param() avec le nom du paramètre auquel nous souhaitons attacher un rappel. Comme vous pouvez le voir, nous recevons un argument id, qui contient le nom du champ. De cette façon, nous chargeons l'objet utilisateur et effectuons la gestion habituelle des erreurs et un simple appel à next() pour passer le contrôle à la précondition ou au gestionnaire d'itinéraire suivant.

app.param("userId", function(req, res, next, id) ( User.get(id, function(err, user) ( if (err) return next(err); if (!user) return next( new Error ("échec de la recherche de l'utilisateur")); req.user = user; next(); )); ));

Les étapes ci-dessus, comme déjà mentionné, améliorent considérablement la lisibilité du code et permettent d'utiliser facilement la même logique à différents endroits de l'application :

app.get("/user/:userId", function(req, res) ( res.send("user " + req.user.name); ));

Rendu des vues

Afficher les noms de fichiers suivent le schéma (nom). (moteur), où (moteur) est le nom du module de moteur de modèle qui doit être connecté. Par exemple, la vue layout.ejs indique au système de vue de faire require("ejs") . Pour s'intégrer à Express, le module chargeable doit exporter une méthode, exports.compile(str, options) et renvoyer une fonction. Pour modifier ce comportement, vous pouvez utiliser la méthode app.register() - elle vous permet d'associer des extensions de fichiers à des moteurs spécifiques. Par exemple, vous pouvez rendre foo.html par le moteur ejs.

Ci-dessous un exemple utilisant Jade pour rendre index.html . Et comme nous n'utilisons pas layout:false , le contenu rendu de la vue index.jade sera transmis en tant que variable de corps locale à la vue layout.jade.

app.get("/", function(req, res) ( res.render("index.jade", ( titre : "Mon site" )); ));

La configuration du moteur d'affichage vous permet de spécifier le moteur de modèle par défaut. Ainsi, par exemple, lorsque vous utilisez Jade, vous pouvez faire ceci :

app.set("moteur d'affichage", "jade");

ce qui nous permettra de rendre ainsi :

res.render("index");

Mais pas comme ça :

res.render("index.jade");

Lorsque le moteur de modèle est installé via le moteur d'affichage, les extensions de fichier ne sont pas nécessaires. Cependant, nous pouvons toujours utiliser plusieurs moteurs de modèles à la fois :

res.render("une autre-page.ejs");

Express dispose également d'un paramètre d'options d'affichage qui sera appliqué à chaque rendu de la vue. Par exemple, si vous n’utilisez pas souvent des mises en page, vous pouvez l’écrire comme ceci :

app.set("options d'affichage", ( mise en page : false ));

Qui peut ensuite être surchargé si nécessaire dans un appel à res.render() :

res.render("myview.ejs", ( mise en page : true ));

Lorsque vous avez besoin d'une mise en page différente, vous pouvez également spécifier le chemin. Par exemple, si le moteur d'affichage est défini sur jade et que le fichier de mise en page s'appelle ./views/mylayout.jade , nous pouvons simplement transmettre :

res.render("page", ( mise en page : "mylayout" ));

Sinon, vous pouvez passer l'extension du fichier :

res.render("page", ( mise en page : "mylayout.jade" ));

Les chemins peuvent également être absolus :

res.render("page", ( mise en page : __dirname + "/../../mylayout.jade" ));

Un bon exemple est la spécification de balises de moteur d'ouverture et de fermeture non standard. ejs:

app.set("options d'affichage", ( open: "((", close: "))" ));

Afficher des fragments

Le système de vue Express prend en charge les fragments et les collections, une sorte de mini-vue. Par exemple, au lieu de parcourir la vue pour afficher une liste de commentaires, vous pouvez simplement utiliser un fragment de collection :

partial("commentaire", (collection : commentaires));

Si d'autres options ou variables locales ne sont pas nécessaires, vous pouvez ignorer l'objet et simplement transmettre le tableau de données. L'exemple ci-dessous est équivalent au précédent :

partial("commentaire", commentaires);

Lorsque nous utilisons des collections, nous disposons de plusieurs variables locales « magiques » :

  • firstInCollection - vrai s'il s'agit du premier objet
  • indexInCollection - index de l'objet dans la collection
  • lastInCollection - vrai s'il s'agit du dernier objet
  • collectionLength - longueur de la collection

Les variables locales transmises ou générées sont prioritaires, mais les variables locales transmises à la vue parent sont également disponibles pour la vue enfant. Ainsi, par exemple, si nous rendons une vue en utilisant partial("blog/post", post) et qu'elle produit une variable locale post et que la vue qui a appelé cette fonction avait une variable locale user , alors l'utilisateur sera également visible dans le blog. /post-vue.

Voir res.partial() pour plus de documentation.

Remarque : utilisez les collections avec précaution, car le rendu d'un tableau de 100 éléments signifie le rendu de 100 vues. Pour les collections simples, il est préférable de parcourir la vue plutôt que d’utiliser des collections. De cette façon, la charge sera moindre.

Rechercher des vues

Les vues sont recherchées par rapport à la vue parent. Par exemple, si nous avons une vue vues/user/list.jade et que nous appelons à l'intérieur partial("edit") , le système essaiera de charger la vue vues/user/edit.jade , alors que partial("../ messages") entraînera le téléchargement de vues/messages.jade

Le système de visualisation vous permet également de créer des fichiers d'index. Par exemple, nous pouvons appeler res.render("users") et cela peut charger à la fois Views/users.jade et Views/users/index.jade .

Vous pouvez également utiliser des fichiers d'index à partir d'une vue dans le même répertoire. Ainsi, appeler partial("users") peut accéder à la vue ../users/index au lieu d'appeler partial("index") .

Moteurs de modèles

Vous trouverez ci-dessous quelques moteurs de modèles couramment utilisés avec Express :

  • E.J.S.- JavaScript intégré
  • CaféKup- basé sur un modèle CaféScript
  • Modèles jQuery pour le nœud

Prise en charge des sessions

La prise en charge des sessions peut être activée à l'aide de la couche de session de Connect. Pour cela également, nous avons besoin d'une couche cookieParser sus-jacente, qui analysera les cookies et les placera dans req.cookies.

app.use(express.cookieParser()); app.use(express.session(( secret: "clavier chat" )));

Par défaut, la couche session utilise le stockage en mémoire de Connect, mais il existe de nombreuses autres solutions. Par exemple connecter-redis prend en charge le stockage de session dans Rédis. Voici comment l'utiliser :

var RedisStore = require("connect-redis")(express); app.use(express.cookieParser()); app.use(express.session(( secret : "clavier chat", magasin : nouveau RedisStore )));

Désormais, les propriétés req.session et req.sessionStore seront disponibles à partir de toutes les routes et couches suivantes. Les propriétés req.session sont automatiquement enregistrées lors de la réponse. Voici comment organiser votre panier :

var RedisStore = require("connect-redis")(express); app.use(express.bodyParser()); app.use(express.cookieParser()); app.use(express.session(( secret : "clavier chat", magasin : nouveau RedisStore ))); app.post("/add-to-cart", function(req, res) ( // disons que nous avons passé plusieurs objets du formulaire // utilisons bodyParser() pour cela var items = req.body.items; req. session.items = items; res.redirect("back"); )); app.get("/add-to-cart", function(req, res) ( // Lorsque nous redirigeons vers GET /add-to-cart // nous pouvons vérifier req.session.items && req.session.items . length // pour imprimer notre message if (req.session.items && req.session.items.length) ( req.flash("info", "Vous avez %s articles dans votre panier", req.session.items. length ); ) res.render("shopping-cart"); ));

L'objet req.session possède également les méthodes Session.touch() , Session.destroy() , Session.regenerate() pour manipuler les sessions. Pour des informations plus complètes, consultez la documentation de la session Connect.

Guide de migration

Les développeurs qui ont travaillé avec Express 1.x peuvent se référer au guide de migration pour faire fonctionner leurs applications avec Express 2.x, Connect 1.x et Node 0.4.x.

Demande

req.header(clé[, valeur par défaut])

Obtenez l'en-tête de demande de clé (insensible à la casse) avec une valeur par défaut facultative :

req.header("Hôte"); req.header("hôte"); req.header("Accepter", "*/*");

Les en-têtes Referrer et Referer constituent un cas particulier ; les deux constructions fonctionneront :

// a envoyé l'en-tête "Referrer : http://google.com" req.header("Referer"); // => "http://google.com" req.header("Référent"); // => "http://google.com"

req.accepte (type)

Vérifie si l'en-tête Accept est transmis et s'il correspond au type donné.

Lorsque l’en-tête Accept est manquant, true est renvoyé. Sinon, le type correspond, puis les sous-types sont vérifiés. Il est possible de transmettre "html" qui est converti en interne en "text/html" à l'aide d'une table de recherche MIME.

// Accepter : text/html req.accepts("html"); // => vrai // Accepte : text/*; application/json req.accepts("html"); req.accepte("texte/html"); req.accepts("text/plain"); req.accepte("application/json"); // => true req.accepts("image/png"); req.accepte("png"); // => faux

req.is(type)

Vérifie la demande entrante pour la présence d'un en-tête Content-Type et correspond au type MIME spécifié.

// Laissez Content-Type: text/html; charset=utf-8 req.is("html"); req.is("text/html"); // => true // Laissez le Content-Type être maintenant application/json req.is("json"); req.is("application/json"); // => true req.is("html"); // => faux

Dans Express, vous pouvez enregistrer vos propres rappels pour diverses vérifications de demandes. Par exemple, disons que nous devons effectuer une vérification minutieuse pour voir si la requête entrante est une image. Pour ce faire, vous pouvez enregistrer le rappel « une image » :

app.is("une image", function(req) ( return 0 == req.headers["content-type"].indexOf("image"); ));

Vous pouvez maintenant l'utiliser dans les gestionnaires de routes pour vérifier le type de contenu du formulaire "image/jpeg", "image/png", etc.

app.post("/image/upload", function(req, res, next) ( if (req.is("une image")) ( // effectuer certaines actions ) else ( next(); ) ));

N'oubliez pas que cette méthode ne s'applique pas uniquement au Content-Type - vous pouvez effectuer tout type de vérification.

Vous pouvez également utiliser des caractères génériques. Cela simplifiera notre exemple d’image. Ici, nous vérifierons uniquement le type :

req.is("image/*");

Nous pouvons également vérifier le sous-type comme indiqué ci-dessous. Ici, la vérification retournera true dans les cas de "application/json" et "text/json" .

req.is("*/json");

req.param(nom[, valeur par défaut])

Renvoie la valeur du nom du paramètre ou - s'il n'existe pas - default .

Vérifie les paramètres de route (req.params), par exemple /user/:id

Vérifie les paramètres de la chaîne de requête (req.query), par exemple ?id=12

Vérifie les paramètres codés en URL du corps de la requête (req.body), par exemple, id=12

Pour recevoir les paramètres du corps de la requête codés en urlen, un objet req.body doit exister. Pour ce faire, activez la couche bodyParser().

req.get (champ, paramètre)

Obtient le paramètre du champ d'en-tête. La valeur par défaut est une chaîne vide.

req.get("content-disposition", "nom de fichier"); // => "quelque chose.png" req.get("Content-Type", "boundary"); // => "--foo-bar-baz"

req.flash(type[, msg])

Met en file d'attente le message contextuel.

req.flash("info", "email envoyé"); req.flash("erreur", "échec de la livraison du courrier électronique"); req.flash("info", "email renvoyé"); // => 2 req.flash("info"); // => ["email envoyé", "email réenvoyé"] req.flash("info"); // => req.flash(); // => ( erreur : ["échec de la livraison par e-mail"], info : )

Les messages contextuels peuvent également utiliser des chaînes de format. La chaîne par défaut "%s" est disponible :

req.flash("info", "échec de la remise du courrier électronique à _%s_ depuis _%s_.", toUser, fromUser);

req.isXMLHttpRequest

Également abrégé req.xhr. Vérifie l'en-tête X-Requested-With pour voir si la requête a été effectuée à l'aide d'un XMLHttpRequest :

req.xhr req.isXMLHttpRequest

Réponse

res.header(clé[, val])

Obtient ou définit l'en-tête de réponse.

res.header("Content-Length"); // => non défini res.header("Content-Length", 123); // => 123 res.header("Content-Length"); // => 123

res.charset

Définit le codage des en-têtes Content-Type suivants. Par exemple, res.send() et res.render() seront par défaut "utf8" et nous pouvons définir explicitement l'encodage avant de restituer le modèle :

res.charset = "ISO-8859-1" ; res.render("utilisateurs");

ou avant de répondre avec res.send() :

res.charset = "ISO-8859-1" ; res.send(str);

ou en utilisant res.end() intégré à Node :

res.charset = "ISO-8859-1" ; res.header("Content-Type", "text/plain"); res.end(str);

res.contentType(type)

Définit l’en-tête de réponse Content-Type.

var filename = "chemin/vers/image.png"; res.contentType(nom de fichier); // Content-Type est maintenant "image/png"

Vous pouvez également définir Content-Type avec la chaîne suivante :

res.contentType("application/json");

Ou simplement l'extension du fichier (sans le point initial) :

res.contentType("json");

res.attachement()

Définit l’en-tête de réponse Content-Disposition sur "attachment" . Facultativement, un nom de fichier peut être transmis.

res.attachment("chemin/vers/mon/image.png");

res.sendfile(chemin[, options[, rappel]])

Utilisé dans res.download() pour transférer un fichier arbitraire.

res.sendfile("chemin/vers/mon.fichier");

Cette méthode prend un paramètre de rappel facultatif, qui est appelé si le transfert de fichier échoue ou réussit. Par défaut, next(err) est appelé, mais si le rappel est passé, cela doit être fait explicitement ou gérer l'erreur.

res.sendfile(path, function(err) ( if (err) ( next(err); ) else ( console.log("transferred %s", path); ) ));

Vous pouvez également transmettre des options à l'appel fs.createReadStream(). Par exemple, pour modifier la taille du tampon :

res.sendfile(path, ( bufferSize: 1024 ), function(err) ( // traitement... ));

res.download(file[, filename[, callback[, callback2]]])

Téléchargez ce fichier en pièce jointe (vous pouvez spécifier un autre nom de fichier facultatif).

res.download('chemin/vers/image.png');

res.download('chemin/vers/image.png', 'foo.png');

Cela équivaut à ce qui suit :

res.attachment(fichier); res.sendfile(fichier);

Facultativement, vous pouvez spécifier un rappel comme deuxième ou troisième argument de res.sendfile() . Dans celui-ci, vous pouvez répondre comme si l'en-tête n'avait pas encore été transmis.

res.download(path, "expenses.doc", function(err) ( // traitement... ));

Vous pouvez également éventuellement transmettre un deuxième rappel - callback2 . Il gère les erreurs liées à la connexion. Toutefois, il ne doit pas tenter d’envoyer une réponse.

res.download(path, function(err) ( // erreur ou terminaison), function(err) ( // erreur de connexion ));

res.send(corps|statut[, en-têtes|statut[, statut]])

La méthode res.send() est une fonction de réponse de haut niveau qui vous permet de transmettre des objets (pour une réponse JSON), des chaînes (pour une réponse HTML), des instances de tampon ou des entiers spécifiant un code d'état (404, 500, etc. .) . Voici comment il est utilisé :

res.send(); // 204 res.send(new Buffer("wahoo")); res.send((certains : "json" )); res.send(""); res.send("Désolé, je ne trouve pas ça", 404); res.send("texte", ( "Content-Type": "text/plain" ), 201); res.send(404);

Par défaut, l'en-tête Content-Type est défini automatiquement. Cependant, s'il a été défini manuellement explicitement dans res.send() ou avant d'utiliser res.header() , ou d'utiliser res.contentType() , il ne sera pas automatiquement défini.

Notez que cette méthode termine la réponse (similaire à res.end()), donc si vous devez produire plusieurs réponses ou un flux, vous devez utiliser res.write() .

res.json(obj[, en-têtes|statut[, statut]])

Envoie une réponse JSON avec des en-têtes et un code d'état facultatifs. Cette méthode est idéale pour organiser une API JSON, mais JSON peut également être envoyé en utilisant res.send(obj) (ce qui n'est pas idéal si vous souhaitez uniquement envoyer une chaîne codée en JSON, puisque res.send(string) enverra du HTML)

res.json(null); res.json((utilisateur : "tj" )); res.json("garde!", 500); res.json("Rien trouvé", 404);

res.redirect(url[, statut])

Redirige vers l'URL spécifiée. Le code d'état par défaut est 302.

res.redirect("/", 301); res.redirect("/compte"); res.redirect("http://google.com"); res.redirect("accueil"); res.redirect("retour");

Express prend en charge les raccourcis pour les redirections – ceux par défaut sont "back" et "home" . Dans ce cas, "back" redirige vers l'URL spécifiée dans l'en-tête Referrer (ou Referer), et "home" utilise le paramètre "home" (par défaut "/").

res.cookie(nom, val[, options])

Définit la valeur du cookie nommé name sur val . Options : httpOnly, sécurisé, expire, etc. L'option path est par défaut la valeur définie dans le paramètre "home", généralement "/" .

// "Se souvenir de moi" pendant 15 minutes res.cookie("rememberme", "yes", ( expires: new Date(Date.now() + 900000), httpOnly: true ));

La propriété maxAge peut être définie pour expirer par rapport à Date.now() en millisecondes. Notre exemple ci-dessus peut donc maintenant être réécrit comme suit :

res.cookie("souviens-toi de moi", "oui", ( maxAge: 900000 ));

Pour analyser les cookies entrants, utilisez la couche cookieParser, qui génère un objet req.cookies :

app.use(express.cookieParser()); app.get("/", function(req, res) ( // utilise req.cookies.rememberme ));

res.clearCookie(nom[, options])

Nous effaçons le cookie nommé name , en attribuant au paramètre expires une date dans un passé lointain. Les options sont les mêmes que pour res.cookie() , le chemin est également par défaut le paramètre "home".

res.clearCookie("souviens-toi de moi");

res.render(view[, options[, fn]])

Rend une vue avec les options données et un rappel fn facultatif. Lorsque fn est donné, la réponse au client n'est pas automatique, sinon une réponse texte/html est effectuée avec le code 200 .

Les options passées sont également des variables de vue locale. Par exemple, si nous voulons transmettre la variable utilisateur et désactiver la mise en page, nous le faisons dans un seul objet :

var utilisateur = ( nom : "tj" ); res.render("index", ( mise en page : false, utilisateur : utilisateur ));

L'objet options est également utilisé pour transmettre des options. Par exemple, si vous transmettez la propriété status, non seulement elle devient disponible pour la vue, mais elle définit également le code d'état de la réponse. Ceci est également utile si le moteur de modèle accepte certaines options, telles que debug ou compress . Vous trouverez ci-dessous un exemple de la façon dont vous pouvez afficher une page d'erreur - le statut est transmis ici à la fois pour l'afficher et pour définir le code d'état res.statusCode .

res.render("erreur", ( statut : 500, message : "Erreur interne du serveur" ));

res.partial(vue[, options])

Rend un fragment avec les options données. Cette méthode est toujours accessible depuis la vue en tant que variable locale.

  • object - l'objet passé à la vue
  • tout comme le nom de la variable qui représentera l'objet objet ou chaque élément de la collection passé à la vue. La valeur par défaut est le nom de la vue.
    • comme : "quelque chose" - ajoutera une variable locale quelque chose
    • as: this - utilisera l'élément de collection comme contexte de vue (this)
    • as: global - fusionnera les propriétés de l'élément de collection et les variables de vue locale
    • collection - un ensemble d'objets. Son nom vient du nom de la vue. Par exemple, video.html contiendra un objet vidéo à l'intérieur.

Les constructions suivantes sont équivalentes les unes aux autres et le nom de collection transmis au fragment sera toujours "movie" .

partial("theatre/movie.jade", (collection : films )); partial("theatre/movie.jade", films); partial("movie.jade", (collection : films )); partial("film.jade", films); partial("film", films); // Dans la vue : moovie.director

Pour changer le nom d'une variable locale de "film" à "vidéo", vous pouvez utiliser l'option as :

partial("film", (collection : films, comme : "vidéo" )); // Dans la vue : video.director

Nous pouvons également définir movie la valeur this dans notre vue afin qu'au lieu de movie.director nous puissions faire référence à this.director .

partial("film", (collection : films, comme : this )); // À l'intérieur de la vue : this.director

Une solution alternative consiste à étendre les propriétés d'un élément de collection en variables pseudo-globales (en fait locales) en utilisant as : global , qui est du sucre syntaxique :

partial("film", (collection : films, as : global )); // À l'intérieur de la vue : réalisateur

La même logique s'applique non seulement aux collections, mais également à un objet dans une vue fragmentée :

partial("film", ( objet : film, comme : this )); // À l'intérieur de la vue : this.director partial("movie", ( object: movie, as: global )); // À l'intérieur de la vue : réalisateur partial("movie", ( object: movie, as: "video" )); // À l'intérieur de la vue : video.director partial("movie", ( object: movie )); // réalisateur de cinéma

Lorsque le deuxième argument n'est pas une collection (sans .length), il est traité comme un objet. Dans ce cas, le nom de la variable locale de cet objet est formé à partir du nom de la vue.

var movie = new Movie("L'Etrange Noël de Monsieur Jack", "Tim Burton") partial("movie", movie) // => Dans la vue : movie.director

L'exception à cette règle est lorsqu'un objet simple ("()" ou "nouvel objet") est transmis, il est alors considéré comme un objet local et n'est pas accessible par son nom dans une vue fragmentée. Par exemple, dans l'exemple suivant, vous vous attendez à ce qu'il y ait une variable locale "movie" , mais comme il s'agit d'un objet simple, les variables locales sont déjà "director" et "title" , c'est-à-dire ses propriétés :

var movie = ( titre : "L'Étrange Noël de Monsieur Jack", réalisateur : "Tim Burton" ); partiel("film", film)

Dans de tels cas, lorsque vous devez transmettre un objet simple, attribuez-le simplement à une propriété ou utilisez la propriété d'objet, qui héritera du nom de l'objet du nom de fichier. Les exemples listés ci-dessous sont équivalents :

partial("film", ( locaux : ( film: film )) partial("film", ( film: film )) partial("film", ( objet: film ))

La même API peut être utilisée à partir d'une route afin que vous puissiez répondre avec un fragment HTML via AJAX ou WebSockets, par exemple vous pouvez restituer une collection d'utilisateurs directement à partir de la route :

app.get("/users", function(req, res) ( if (req.xhr) ( // envoie en réponse chaque utilisateur de la collection // passé à la vue "user" res.partial("user", users) ; ) else ( // répond avec une mise en page complète avec une page de liste d'utilisateurs // dont le modèle fait partial("user", users) // et ajoute une sorte d'interface res.render("users", ( utilisateurs : utilisateurs ) ); ) ));

res.local(nom[, val])

Obtenez ou définissez la variable locale spécifiée. Dans ce cas, les variables locales font référence aux variables transmises aux méthodes de rendu de la vue, telles que res.render() .

app.all("/movie/:id", function(req, res, next) ( Movie.get(req.params.id, function(err, movie) ( // Effectue l'affectation res.locals.movie = movie res .local("film", film); )); )); app.get("/movie/:id", function(req, res) ( // la variable locale movie existe déjà // mais on peut l'ajouter si besoin res.render("movie", ( displayReviews: true ) ); ));

res.locals(obj)

Attribuez plusieurs variables locales à l’aide de l’objet obj donné. Ce qui suit est équivalent :

res.local("foo", bar); res.local("bar", baz); res.locals(( foo: bar, bar, baz ));

Serveur

app.set(nom[, val])

Définissez le paramètre de nom de l'application sur val , ou obtenez la valeur du paramètre de nom si val est manquant :

app.set("views", __dirname + "/views"); app.set("vues"); // => ...chemin...

Vous pouvez également accéder aux paramètres via appsettings :

app.settings.views // => ...chemin...

app.enable(nom)

Définit le paramètre de nom sur true :

app.enable("un paramètre arbitraire"); app.set("un paramètre arbitraire"); // => true app.enabled("un paramètre arbitraire"); // => vrai

app.enabled(nom)

Vérifie si le paramètre de nom est vrai :

app.enabled("afficher le cache"); // => false app.enable("afficher le cache"); app.enabled("afficher le cache"); // => vrai

app.disable(nom)

Définissez le paramètre de nom sur false :

app.disable("certains paramètres"); app.set("certains paramètres"); // => false app.disabled("certains paramètres"); // => faux

app.disabled(nom)

Vérifie si le paramètre de nom est faux :

app.enable("afficher le cache"); app.disabled("afficher le cache"); // => false app.disable("afficher le cache"); app.disabled("afficher le cache"); // => vrai

app.configure(env|fonction[, fonction])

Spécifie la fonction de rappel pour l'environnement env (ou pour tous les environnements) :

app.configure(function() ( // s'exécute pour tous les environnements)); app.configure("development", function() ( // exécuté uniquement pour l'environnement "development"));

app.redirect(nom, val)

Pour res.redirect(), nous pouvons définir des raccourcis (dans le champ d'application) comme ci-dessous :

app.redirect("google", "http://google.com");

Maintenant, dans l'itinéraire, nous pouvons appeler :

res.redirect("google");

Vous pouvez également faire des abréviations dynamiques :

app.redirect("comments", function(req, res) ( return "/post/" + req.params.id + "/comments"; ));

Vous pouvez maintenant effectuer les opérations suivantes et la redirection sera construite dynamiquement en fonction du contexte de la demande. Si nous avons appelé la route avec GET /post/12, notre redirection sera /post/12/comments.

app.get("/post/:id", function(req, res) ( res.redirect("comments"); ));

Dans le cas d'une application montée, res.redirect() prendra en compte le point de montage de l'application. Par exemple, si l'application de blog est montée sur /blog , l'exemple suivant redirigera vers /blog/posts :

res.redirect("/posts");

app.erreur (fonction)

Ajoute une fonction de gestionnaire d'erreurs dont le premier paramètre acceptera toutes les exceptions, comme indiqué ci-dessous. Notez qu'il est possible de définir plusieurs gestionnaires d'erreurs en appelant cette méthode plusieurs fois, cependant la méthode doit appeler next() si elle ne veut pas gérer l'exception elle-même :

app.error(function(err, req, res, next) ( res.send(err.message, 500); ));

app.helpers(obj)

Enregistre les assistants de vue statique.

app.helpers(( nom : fonction (premier, dernier) ( return first + ", " + last ), firstName : "tj", lastName : "holowaychuk" ));

Notre vue peut désormais utiliser les variables firstName et lastName et la fonction name().

<%= name(firstName, lastName) %>

Express fournit également plusieurs variables locales par défaut :

  • paramètres - objet de paramètres d'application
  • layout(path) spécifie la mise en page directement depuis l'intérieur de la vue

Cette méthode est alias app.locals() .

app.dynamicHelpers(obj) (#app.dynamic-helpers)

Enregistre les assistants de vue dynamique. Les assistants de vue dynamiques sont simplement des fonctions qui prennent res , req et sont exécutées dans le contexte de l'instance du serveur avant de restituer une vue. La valeur de retour d'une telle fonction devient une variable locale à laquelle la fonction est associée.

app.dynamicHelpers(( session: function(req, res) ( return req.session; ) ));

Désormais, toutes nos vues auront accès à la session - les données de session seront disponibles à la manière de session.name, etc. :

<%= session.name %>

app.lookup

Renvoie les gestionnaires de route associés au chemin donné.

Disons qu'il existe ces itinéraires :

Vous pouvez utiliser la fonctionnalité de recherche pour vérifier quels itinéraires sont spécifiés. Cela peut être utile pour les frameworks de niveau supérieur construits sur Express.

app.lookup.get("/user/:id"); // => app.lookup.get("/user/:id/:op?"); // => app.lookup.put("/user/:id"); // => app.lookup.all("/user/:id"); // => app.lookup.all("/hé"); // =>

L'alias de app.lookup.HTTP_METHOD() est simplement app.HTTP_METHOD() - sans l'argument de rappel. C'est la réduction. Par exemple, ce qui suit est équivalent :

app.lookup.get("/user"); app.get("/user");

Chaque fonction renvoyée est complétée par des propriétés utiles :

var fn = app.get("/user/:id/:op?"); fn.regexp // => /^\/user\/(?:([^\/]+?))(?:\/([^\/]+?))?\/?$/i fn .keys // => ["id", "op"] fn.path // => "/user/:id/:op?" fn.method // => "OBTENIR"

app.match

Renvoie un tableau de fonctions de rappel qui se déclenchent sur l'URL donnée, qui peuvent contenir une chaîne de requête, etc. Cela peut être utile pour comprendre quelles routes ont la capacité de répondre.

Disons que nous avons les itinéraires suivants :

app.get("/user/:id", function() ()); app.put("/user/:id", function() ()); app.get("/user/:id/:op?", function() ());

L'appel de match sur GET renverra deux fonctions car le :op dans la dernière route est un paramètre facultatif.

app.match.get("/user/1"); // =>

Et le prochain appel ne renverra qu'un seul rappel pour /user/:id/:op? .

app.match.get("/user/23/edit"); // =>

Nous pouvons également utiliser all() si la méthode HTTP n'est pas importante pour nous

app.match.all("/user/20"); // =>

Chaque fonction est dotée des propriétés suivantes :

var fn = app.match.get("/user/23/edit"); fn.keys // => ["id", "op"] fn.params // => ( id : "23", op : "edit" ) fn.method // => "GET"

app.monté (fn)

Attribuez un rappel à fn qui est appelé lorsque ce serveur est transmis à Server.use() .

var app = express.createServer(), blog = express.createServer(); blog.mount(function(parent) ( //le parent est une application // ceci est un blog )); app.use(blog);

app.register (ext, exportations)

Associe les propriétés d'exportation spécifiées (exportations) du moteur de modèle à l'extension ext du fichier modèle.

app.register(".html", require("jade"));

Cela peut également être utile dans le cas de bibliothèques dont le nom ne correspond pas exactement à l'extension du fichier modèle. Exemple vivant - Haml.js, qui est installé npm-om comme "hamljs" et nous pouvons l'enregistrer avec des modèles ".haml" plutôt que ".hamljs" comme ce serait la valeur par défaut :

app.register(".haml", require("haml-js"));

De plus, app.register est très utile dans le cas de moteurs de modèles dont l'API n'est pas conforme aux spécifications Express. Dans l'exemple ci-dessous nous associons l'extension .md au moteur de rendu réduction-des dossiers. Nous effectuerons le rendu en HTML uniquement la première fois - pour de meilleures performances - et nous prendrons en charge la substitution de variable de la forme "(nom)".

app.register(".md", ( compile: function(str, options) ( var html = md.toHTML(str); return function(locals) ( return html.replace(/\(([^)]+) \)/g, function(_, name) ( return locals; )); ); ) ));

app.écouter()

Nous lions le socket du serveur d'application à l'adresse host:port. Le port par défaut est 3000, l'hôte est INADDR_ANY.

app.écouter(); app.écouter (3000); app.listen(3000, "n.n.n.n");

L'argument port peut également être une chaîne représentant le chemin d'accès à socket de domaine Unix:

app.listen("/tmp/express.sock");

Essayons maintenant :

$ telnet /tmp/express.sock GET / HTTP/1.1 HTTP/1.1 200 OK Type de contenu : text/plain Longueur du contenu : 11 Hello World

Acteurs du projet

Les principaux contributeurs au projet étaient les suivants :

  • TJ Holowaychuk (visionmedia)
  • Ciaran Jessup (ciaranj)
  • Aaron Heckmann (aheckmann)
  • Guillermo Rauch (guille)

Modules tiers

Les modules suivants fonctionnent avec ou sont construits sur Express :

  • fournit le routage des ressources
  • messages express rendant les notifications contextuelles
  • Prise en charge express-configure pour la configuration asynchrone (chargement de données depuis Redis, etc.)
  • express-namespace - espaces de noms dans les routes
  • express-expose publie simplement le code JS côté client de l'application
  • express-params - extensions app.param()
  • express-mongoose - plugin pour restituer facilement les résultats des requêtes Mongoose (ORM pour MongoDB)
  • Traduction

Pour un nouveau programmeur, développer pour Node.js peut sembler un cauchemar. Le coupable est la flexibilité de la plateforme et le manque de directives claires. Mais en fait, tout n’est pas si effrayant.


Par exemple, voici une tâche typique : développer une API REST, la partie serveur d'une application. L'abondance des capacités propres de Node et les nombreux modules supplémentaires qui peuvent aider à résoudre ce problème peuvent conduire un débutant dans une impasse en raison de la richesse du choix. Les principaux problèmes ici sont la sélection des composants et la manière dont ils fonctionnent ensemble.

Une façon de créer une application côté serveur consiste à utiliser une combinaison de Node.js, du framework Express et du SGBD MongoDB. En fait, aujourd'hui, je vais parler de la façon de créer une maquette d'API fonctionnelle pouvant servir de base à presque toutes les applications. Ici, nous allons implémenter des routes REST de base, interagir avec l'API via HTTP et utiliser des options de base de données simples.

Afin de maîtriser avec succès ce matériel, vous devez comprendre ce qu'est l'API REST, comprendre les opérations CRUD et avoir des connaissances de base en JavaScript. J'utilise ES6 ici, rien de bien compliqué, principalement des fonctions fléchées.

Nous développerons un squelette backend pour une application de prise de notes similaire à Google Keep. Dans ce cas, il sera possible d'effectuer les quatre actions CRUD avec des notes, à savoir créer, lire, mettre à jour et supprimer.

Préparation préliminaire

Si vous n'avez pas encore Node, c'est le moment de l'installer. Après l'installation, créez un dossier et exécutez la commande pour y initialiser un nouveau projet :

initialisation Npm
Lors de l'initialisation, répondez aux questions, donnez notamment à l'application un nom « notable » (ou, si vous préférez, tout autre nom).

Le fichier devrait maintenant apparaître dans le dossier package.json. Cela signifie que vous pouvez commencer à installer des packages supplémentaires dont dépend le projet.

Nous prévoyons d'utiliser Express comme framework. Le système de gestion de base de données sera MongoDB. De plus, comme outil auxiliaire pour travailler avec JSON, nous utilisons le package body-parser. Installons tout ça :

Npm install --save express body-parser mongodb
De plus, je recommande fortement d'installer Nodemon en tant que dépendance de développement. C'est un simple petit package qui, lorsque les fichiers changent, redémarre automatiquement le serveur.

Pour installer ce package, exécutez la commande :

Npm install --save-dev nodemon
Ensuite, vous pouvez ajouter le script suivant au fichier package.json:

// package.json "scripts": ("dev": "nodemon server.js" ),
Prêt package.json ressemblera à ceci :

// package.json ( "name": "notable", "version": "1.0.0", "description": "", "main": "server.js", "scripts": ( "dev": "nodemon server.js", "author": "", "license": "ISC", "dependencies": ( "body-parser": "^1.15.2", "express": "^4.14.0 " , "mongodb": "^2.2.16" ), "devDependencies": ( "nodemon": "^1.11.0" ) )
Créons maintenant un fichier serveur.js et commençons à travailler sur l'API.

Serveur

Commençons par connecter les dépendances dans le fichier serveur.js.

// serveur.js const express = require("express"); const MongoClient = require("mongodb").MongoClient; const bodyParser = require("body-parser"); const app = express();
Nous utiliserons MongoClient pour interagir avec la base de données. De plus, nous initialisons ici la constante app, symbolisant notre application, avec une instance du framework Express. Pour que le serveur fonctionne, il ne reste plus qu'à dire à l'application de commencer à écouter les requêtes HTTP.

Ici, nous spécifions le port et commençons à écouter comme suit :

// port const du serveur.js = 8000 ; app.écouter (port, () =>
Désormais, si vous exécutez la commande npm run dev (ou - node server.js si vous n'avez pas installé Nodemon), le message devrait apparaître dans le terminal : « Nous sommes en direct sur le port 8000 ».

Le serveur fonctionne donc. Mais maintenant, il ne fait absolument rien d'utile. Voyons cela.

Itinéraires ciblant les opérations CRUD

Nous prévoyons de créer 4 itinéraires. À savoir:
  • CRÉER – créer des notes.
  • LIRE – lire des notes.
  • MISE À JOUR – mise à jour des notes.
  • SUPPRIMER : supprimer des notes.
Une fois que vous maîtriserez ce schéma, vous serez en mesure de comprendre comment, à l'aide de Node, organiser presque tous les itinéraires REST nécessaires.

Afin de tester l'API, vous aurez besoin de quelque chose qui puisse simuler les requêtes du côté client de l'application. Un excellent programme appelé Postman nous aidera à résoudre ce problème. Il vous permet d'effectuer des requêtes HTTP simples avec un corps et des paramètres donnés.

Installez Facteur. Tout est maintenant prêt pour configurer les itinéraires.

À propos de la structure du projet

La plupart des didacticiels Node.js (et de nombreuses applications réelles) placent toutes les routes dans un seul gros fichier. route.js. Je n'aime pas vraiment cette approche. Si vous organisez les fichiers dans différents dossiers, cela améliorera la lisibilité du code et facilitera la gestion de l'application.

Notre application ne peut pas être qualifiée de grande, mais je propose de tout faire comme il se doit, en tenant néanmoins compte de son échelle modeste. Créez les dossiers suivants : dossier application, et à l'intérieur - itinéraires. Dans le dossier itinéraires créer des fichiers index.js Et note_routes.js. En d’autres termes, la structure du projet ressemblera à ceci : racine > application > routes > index.js Et note_routes.js.

Application Mkdir Application cd Routes mkdir Routes cd Touch index.js Touch note_routes.js
Cette structure peut paraître redondante pour une petite application, mais elle sera très utile dans un système plus vaste construit sur la base de notre exemple. De plus, il est préférable de démarrer tout projet en utilisant les meilleures pratiques existantes.

Création de notes : CRÉER un itinéraire

Commençons par la route CREATE. Pour ce faire, nous répondrons à la question : « Comment créer une note ?
Avant de commencer à créer des notes, nous devrons étendre l'infrastructure de l'application. Dans Express, les routes sont enveloppées dans une fonction qui prend une instance Express et une base de données comme arguments.

Cela pourrait ressembler à ceci :

// routes/note_routes.js module.exports = function(app, db) ( );
Vous pouvez maintenant exporter cette fonction via index.js:

// routes/index.js const noteRoutes = require("./note_routes"); module.exports = function(app, db) ( noteRoutes(app, db); // Il y aura d'autres gestionnaires de routes ici plus tard );
Nous importons ce dans quoi nous sommes entrés serveur.js:

// serveur.js const express = require("express"); const MongoClient = require("mongodb").MongoClient; const bodyParser = require("body-parser"); const app = express(); port const = 8000 ; require("./app/routes")(app, ()); app.listen(port, () => ( console.log("Nous sommes en direct sur " + port); ));
Veuillez noter que puisque nous n'avons pas encore configuré la base de données, un objet vide est passé comme deuxième argument.

Maintenant, nous créons la route CREATE. La syntaxe ici est assez simple :

Module.exports = function(app, db) ( app.post("/notes", (req, res) => ( // Nous allons créer une note ici. res.send("Bonjour") )); );
Lorsqu'une application reçoit une requête POST via le chemin '/notes', elle exécutera le code à l'intérieur de la fonction de rappel, en lui transmettant un objet de requête (qui contient les paramètres de la requête ou les données JSON) et un objet de réponse (qui, bien sûr, est utilisé pour la réponse).

Ce que nous avons réalisé peut déjà être testé. Envoyons, à l'aide de Postman, une requête POST à ​​l'adresse hôte local : 8 000/notes.


La réponse à la demande doit être « Bonjour »

Super. Le premier itinéraire a été créé. L'étape suivante consiste à ajouter des paramètres à la requête, à les traiter dans l'API et enfin à enregistrer la note dans la base de données.

Paramètres de la demande

Dans Postman, allez dans l'onglet Corps et ajoutez plusieurs paires clé-valeur en sélectionnant le bouton radio x-www-form-urlencoded. A savoir, la première clé sera titre, sa valeur est Titre de ma note. Deuxième clé - corps, sa valeur est Quelle belle note.

Cela ajoutera des données codées à la demande qui pourront être traitées par l'API.


Le titre de ma note et le message lui-même sont très simples, mais ici vous pouvez faire preuve d'imagination

Dans le fichier note_route.js, imprimez simplement le corps de la note sur la console.

// note_routes.js module.exports = function(app, db) ( app.post("/notes", (req, res) => ( console.log(req.body) res.send("Bonjour") ) ); );
Essayez d'envoyer une demande en utilisant Postman et vous verrez... non défini.

Malheureusement, Express ne peut pas gérer seul les formulaires codés en URL. Ici, le package body-parser précédemment installé nous viendra en aide.

// serveur.js const express = require("express"); const MongoClient = require("mongodb").MongoClient; const bodyParser = require("body-parser"); const app = express(); port const = 8000 ; app.use(bodyParser.urlencoded(( extended: true ))); require("./app/routes")(app, ()); app.listen(port, () => ( console.log("Nous sommes en direct sur " + port); ));
Désormais, après avoir exécuté une requête POST, son corps peut être vu dans le terminal en tant qu'objet.

(titre : "Titre de ma note", corps : "Quelle superbe note.")
Pour que la première voie fonctionne pleinement, il ne reste plus qu'à configurer la base de données et à y ajouter une note.

Pour créer et configurer rapidement une base de données, nous utiliserons le service mLab. Il est facile de travailler avec et pour de petites quantités d'informations, il est gratuit.

Créez un compte sur le site Web mLab et déployez une nouvelle base de données MongoDB. Pour cela, cliquez sur le bouton Créer Nouveau Au chapitre Déploiements MongoDB, dans la fenêtre qui apparaît, dans la section Plan, sélectionner Nœud unique. Sur la liste Ligne Standard, sélectionner bac à sable et donnez un nom à la base de données. Ensuite, dans la fenêtre de gestion de la base de données, allez dans l'onglet Utilisateurs et ajoutez un utilisateur de base de données en spécifiant un nom d'utilisateur et un mot de passe.


Nouvel utilisateur de la base de données

Copiez la deuxième URL de la même page - la chaîne de connexion à la base de données.


URL pour se connecter à la base de données

Ajouter un répertoire à la racine du projet configuration, créez un fichier dedans db.js.

Mkdir config cd config touch db.js
Pour déposer db.js ajoutez ce qui suit :

Module.exports = (url : votre URL ira ici) ;
N'oubliez pas d'ajouter votre nom d'utilisateur et votre mot de passe à l'URL (pas ceux de votre compte mLab, mais ceux que vous avez créés pour la base de données). Si vous hébergez le projet sur Github, assurez-vous d'inclure le fichier .gitignore(comme ça). De cette façon, vous ne rendrez pas publics le nom et le mot de passe pour travailler avec la base de données.

Maintenant en serveur.js, vous pouvez utiliser MongoClient pour vous connecter à la base de données et envelopper les paramètres de l'application dans une fonction qui lui est transmise lors de la création :

// serveur.js const express = require("express"); const MongoClient = require("mongodb").MongoClient; const bodyParser = require("body-parser"); const db = require("./config/db"); const app = express(); port const = 8000 ; app.use(bodyParser.urlencoded(( extended: true ))); MongoClient.connect(db.url, (err, base de données) => ( if (err) return console.log(err) require("./app/routes")(app, base de données); app.listen(port, ( ) => ( console.log("Nous sommes en direct sur " + port); )); ))
Ceci termine la préparation de l’infrastructure. Désormais, nous traiterons exclusivement des chemins.

Ajout d'enregistrements à la base de données

MongoDB stocke les données dans des collections qui portent bien leur nom. Dans notre cas, les notes seront stockées dans une collection qui, comme vous pouvez le deviner, sera appelée notes .

Lors de la configuration du client, une chaîne de connexion à la base de données lui a été fournie, l'argument db. Dans le code de route, vous pouvez accéder à la base de données comme ceci :

Db.collection("notes")
Créer une note dans la base de données équivaut à appeler la commande insert pour la collection de notes :

Const note = ( texte : req.body.body, titre : req.body.title) db.collection("notes").insert(note, (err, results) => ( )
Une fois la commande terminée avec succès (ou après son échec pour une raison quelconque), vous devez répondre avec l'objet note nouvellement créé ou avec un message d'erreur. Voici le code note_routes.js, complété en tenant compte de ces considérations :

// note_routes.js module.exports = function(app, db) ( app.post("/notes", (req, res) => ( const note = ( texte : req.body.body, titre : req.body .title ); db.collection("notes").insert(note, (erreur, résultat) =>
Essayez ce que vous obtenez. Envoyer une requête POST depuis Postman (avec le drapeau x-www-form-urlencoded), en paramétrant sur l'onglet Corps valeurs des champs titre Et corps.

La réponse devrait ressembler à ceci :


Ajout réussi d'un enregistrement à la base de données

Notes de lecture : LIRE Itinéraire

L'infrastructure que nous avons préparée ci-dessus est adaptée à tous les itinéraires, donc désormais les choses iront plus vite.

Nous allons donc interroger la note que nous venons de créer en suivant le chemin localhost:8000/notes/(identifiant des notes). Dans notre cas, le chemin ressemblera à ceci : hôte local : 8000/notes/585182bd42ac5b07a9755ea3.

Si vous n'avez pas l'ID d'une des notes déjà créées, vous pouvez consulter la base de données sur mLab et l'y trouver, ou créer une nouvelle note et copier son ID.

Voilà à quoi ça ressemble dans note_route.js:

// note_routes.js module.exports = function(app, db) ( app.get("/notes/:id", (req, res) => ( )); app.post("/notes", (req , res) => ( const note = ( texte : req.body.body, titre : req.body.title ); db.collection("notes").insert(note, (err, result) => ( if ( err) ( res.send(( "error": "Une erreur s'est produite" )); ) else ( res.send(result.ops); ) )); )); );
Comme avant, nous allons appeler une commande sur la collection de base de données Notes. Utilisons la méthode findOne pour cela.

// note_routes.js module.exports = function(app, db) ( app.get("/notes/:id", (req, res) => ( const détails = ( "_id":<ТУТ БУДЕТ ID>); db.collection("notes").findOne(details, (err, item) => ( if (err) ( res.send(("error": "Une erreur s'est produite")); ) else ( res.send (article); ) )); )); app.post("/notes", (req, res) => ( const note = ( texte : req.body.body, titre : req.body.title ); db.collection("notes").insert(note , (err, result) => ( if (err) ( res.send(( "error": "Une erreur s'est produite" )); ) else ( res.send(result.ops); ) )); )) ; );
L'identifiant peut être extrait des paramètres d'URL à l'aide de la construction req.params.id. Cependant, si vous insérez simplement la ligne à la place<<>> à partir du code ci-dessus, cela ne fonctionnera pas.

MongoDB nécessite l'ID non pas sous forme de chaîne, mais sous forme d'objet spécial. On l'appelle ID d'objet.

Voici ce que nous avons obtenu après quelques modifications mineures :

// note_routes.js var ObjectID = require("mongodb").ObjectID; module.exports = function(app, db) ( app.get("/notes/:id", (req, res) => ( const id = req.params.id; const détails = ( "_id": nouvel ObjectID (id) ); db.collection("notes").findOne(details, (err, item) => ( if (err) ( res.send(("error": "Une erreur s'est produite")); ) else ( res.send(item); ) )); )); app.post("/notes", (req, res) => ( const note = ( texte : req.body.body, titre : req.body .title ); db.collection("notes").insert(note, (err, result) => ( if (err) ( res.send(( "error": "Une erreur s'est produite" )); ) else ( res.send(result.ops); ) )); )); );
Essayez ceci avec l'un des identifiants de note disponibles dans la base de données. La réponse dans Postman devrait ressembler à ceci :


Demande réussie d'une note de la base de données

Suppression de notes : SUPPRIMER l'itinéraire

Supprimer des objets revient pratiquement à les rechercher dans la base de données. Ce n'est qu'à la place de la fonction findOne que la fonction Remove est utilisée. Voici le code complet du chemin correspondant. Cela met en évidence ce qui est différent du code de la méthode existante qui gère la requête GET.

// note_routes.js // ... app.delete("/notes/:id", (req, res) => ( const id = req.params.id; const détails = ( "_id": new ObjectID( id) ); db.collection("notes").remove(details, (err, item) => ( if (err) ( res.send(("error": "Une erreur s'est produite")); ) else ( res.send("Note " + id + " supprimé ! "); ) )); )); //...

Mise à jour des notes : MISE À JOUR de l'itinéraire

Et voici le dernier itinéraire. Le traitement d'une requête PUT est essentiellement un hybride des opérations READ et CREATE. Vous devez d'abord rechercher l'objet, puis le mettre à jour conformément aux données reçues dans la demande. Maintenant, si vous avez supprimé votre seule note lors du test de l'extrait de code précédent, créez-en une autre.

Voici le code de route de mise à jour des notes :

// note_routes.js // ... app.put ("/notes/:id", (req, res) => ( const id = req.params.id; const détails = ( "_id": new ObjectID( id) ); const note = ( texte : req.body.body, titre : req.body.title ); db.collection("notes").update(détails, note, (erreur, résultat) => ( if ( err) ( res.send(("error": "Une erreur s'est produite")); ) else ( res.send(note); ) )); )); //...
Désormais, n'importe quelle note peut être modifiée. Voici à quoi cela ressemble :


Mise à jour réussie des notes

Notez le défaut dans notre exemple. Si la requête PUT ne contient pas le corps ou le titre de la note, les champs correspondants dans la base de données seront simplement effacés.

Je n'ai pas chargé l'exemple avec des vérifications supplémentaires. Si vous le souhaitez, vous pouvez modifier vous-même l'opération de mise à jour des notes, en ajoutant de nouvelles données à la base de données uniquement si la demande est correctement formée.

Résultats

Vous disposez désormais d'une API Node fonctionnelle qui prend en charge quatre opérations CRUD de base. La partie serveur de l'application peut, en répondant aux requêtes HTTP des clients, créer des notes dans la base de données, les retrouver, les supprimer et les modifier.

L'objectif principal de mon histoire est de faire découvrir à tous la combinaison Node + Express + MongoDB et la méthodologie de développement d'applications serveur. Bien entendu, si c'est aujourd'hui votre première connaissance de ces outils, afin de mieux tout comprendre, vous devrez lire la documentation. Cependant, comprendre ce qui se passe vous permettra de combler rapidement les lacunes de connaissances et de commencer à travailler sur vos propres projets, en utilisant comme point de départ l'application sur laquelle nous avons travaillé ici.

Si vous avez de l'expérience avec Node.js, Express et MongoDB dans des projets réels, avez-vous des conseils pour les débutants ? Et si vous venez d'essayer tout cela pour la première fois, nous attendons vos impressions.

Express est un framework Web populaire écrit en JavaScript et exécuté dans le runtime node.js. Ce module couvre certains des principaux avantages de ce framework, la configuration d'un environnement de développement et l'exécution de tâches de base de développement et de déploiement Web.

Conditions préalables

Avant de commencer ce module, vous devez avoir une idée de ce que sont la programmation côté serveur et les frameworks Web, de préférence en lisant les articles d'un autre module Premières étapes de programmation de sites Web côté serveur. La connaissance des concepts de programmation de base et du langage de programmation JavaScript sera très utile, mais n'est pas requise pour comprendre les concepts de base de ce module.

La note: Ce site Web contient de nombreuses sources pour apprendre JavaScript dans le cadre du développement côté client: JavaScript, Guide JavaScript, Bases de JavaScript, JavaScript (apprentissage). Les fonctionnalités et concepts clés du langage JavaScript restent similaires pour le développement côté serveur sur Node.js et le matériel utilisé est tout à fait pertinent. Node.js fournit des API supplémentaires pour fournir des fonctionnalités utiles pour le développement « sans navigateur », c'est-à-dire pour créer un serveur HTTP et accéder au système de fichiers, mais ne prend pas en charge les API JavaScript pour travailler avec le navigateur et le DOM.

Ce guide vous fournira des informations sur l'utilisation de Node.js et Express, mais il existe également de nombreuses autres excellentes ressources en ligne et dans des livres - certaines d'entre elles sont disponibles dans Comment démarrer avec Node.js (StackOverflow) et (Quora) sujets.

Guides

Introduction à Express/Node Dans le premier article sur Express, nous répondrons aux questions « Qu'est-ce que Node ? et "Qu'est-ce qu'Express ?" et vous donner une idée de ce qui rend le framework web Express spécial. Nous couvrirons les fonctionnalités de base et vous montrerons certains des éléments de base des applications Express (bien qu'à ce stade, vous ne disposiez pas encore d'un environnement de développement pour les tester). Mise en place d'un environnement de développement Node (Express)

Maintenant que vous savez ce qu'est Express, nous allons vous montrer comment configurer et tester un environnement de développement Node/Express sous Windows, Linux (Ubuntu) et Mac OS X. Quel que soit le système d'exploitation populaire que vous utilisez, cet articlevous donnera ce dont vous avez besoin pour commencer à développer des applications Express.

Manuel express : site Web LocalLibrary

Le premier article de notre série pratique explique ce que vous allez apprendre et donne un aperçu du site Web de la « bibliothèque locale » sur lequel nous travaillerons et développerons dans les articles suivants.

Tutoriel express, partie 2 : Création d'un squelette de site Web

Cet article montre comment créer un "squelette".site Web, qui peut ensuite être alimenté à l'aide d'itinéraires de site, de modèles/vues et de bases de données.

Tutoriel Express, partie 3 : Utilisation d'une base de données (avec Mongoose) Cet article présente brièvement les bases de données pour Node/Express. Il montre ensuite comment nous pouvons utiliser Mongoose pour fournir un accès à la base de données pour le site. Bibliothèque locale. La leçon explique comment le schéma d'objet et les modèles sont déclarés, les types de champs de base et la validation de base. Certains des principaux moyens d'accéder aux données du modèle sont également brièvement présentés. Tutoriel Express Partie 4 : Routes et contrôleurs Dans ce didacticiel, nous allons créer des routes (code de gestion d'URL) avec un gestionnaire de fonctions « factice » pour tous les points de terminaison de ressources dont nous aurons éventuellement besoin pour le site. Bibliothèque locale. Une fois terminé, nous aurons une structure modulaire pour notre code de gestion des itinéraires, que nous pourrons étendre avec de véritables fonctions de gestionnaire dans les prochains articles. Nous comprendrons également très bien comment créer des itinéraires modulaires à l’aide d’Express. Tutoriel express, partie 5 : Afficher les données de la bibliothèque Nous sommes maintenant prêts à ajouter les pages qui afficheront les livres du site Web. Bibliothèque locale et d'autres données. Les pages comprendront une page principale qui montre le nombre d'enregistrements d'un certain type dont nous disposons et une page séparée pour visualiser l'enregistrement en détail. En cours de route, nous acquerrons une expérience pratique dans la récupération d'enregistrements à partir de bases de données et l'utilisation de modèles. Tutoriel Express Partie 6 : Travailler avec des formulaires Dans cette partie, nous allons vous montrer comment travailler avec des formulaires HTML dans Express à l'aide de Pug, et en particulier comment créer, mettre à jour et supprimer des documents de la base de données. Tutoriel Express, Partie 7 : Mise en page en production Maintenant que vous avez créé un site Web incroyable Bibliothèque locale, vous souhaiterez l'installer sur un serveur public afin qu'il puisse permettre au personnel de la bibliothèque et aux utilisateurs d'accéder à Internet. Cet article donne un aperçu de la manière dont vous pouvez trouver un hébergeur sur lequel déployer votre site et de ce que vous devez faire pour que votre site soit prêt à être publié. Installation de LocalLibrary sur PWS/Cloud Foundry Cet article fournit une démonstration pratique de la façon d'installer Bibliothèque locale sur le Cloud Pivotal Web Services PaaS est une alternative open source complète à Heroku, le service cloud PaaS utilisé dans la partie 7 de ce didacticiel présenté ci-dessus. PWS/Cloud Foundry vaut vraiment la peine d'être essayé si vous recherchez une alternative à Heroku (ou un autre service cloud PaaS), ou si vous souhaitez simplement essayer quelque chose de différent.