Introduction aux générateurs et Koa.js Partie 2

Ce que vous allez créer

Bienvenue dans la deuxième partie de notre série sur les générateurs et Koa. Si vous l'avez manqué, vous pouvez lire la partie 1 ici. Avant de commencer le processus de développement, assurez-vous d'avoir installé Node.js 0.11.9 ou supérieur..

Dans cette partie, nous allons créer une API de dictionnaire à l'aide de Koa.js, et vous en apprendrez plus sur le routage, la compression, la journalisation, la limitation de débit et la gestion des erreurs dans Koa.js. Nous utiliserons également Mongo comme magasin de données et apprendrons brièvement comment importer des données dans Mongo et la facilité offerte par les requêtes dans Koa. Enfin, nous examinerons le débogage des applications Koa..

Comprendre Koa

Koa a construit sous son capot des changements radicaux qui exploitent les avantages du générateur de l'ES6. Outre le changement dans le flux de contrôle, Koa introduit ses propres objets personnalisés, tels que ce, cette demande, et this.response, qui agissent commodément comme une couche de sucre syntaxique construite sur les objets req et res de Node, vous donnant accès à diverses méthodes pratiques et à des getters / setters. 

En plus de la commodité, Koa nettoie également le middleware qui, dans Express, s’appuyait sur d’incroyables hacks qui modifiaient souvent les objets principaux. Il fournit également une meilleure gestion des flux.

Attendez, c'est quoi un middleware?

Un middleware est une fonction connectable qui ajoute ou supprime une fonctionnalité particulière en effectuant des travaux dans les objets requête / réponse de Node.js..

Le middleware de Koa

Un middleware Koa est essentiellement une fonction génératrice qui renvoie une fonction génératrice et en accepte une autre. Généralement, une application possède une série de middleware exécutés pour chaque requête.. 

En outre, un middleware doit céder le passage au prochain middleware «en aval» s'il est géré par un «middleware en amont». Nous discuterons plus à ce sujet dans la section de gestion des erreurs.

Bâtiment middleware

Une dernière chose: pour ajouter un middleware à votre application Koa, nous utilisons le koa.use () méthode et fournir la fonction middleware comme argument. Exemple: app.use (koa-logger) ajoute koa-logger à la liste des middleware que notre application utilise.

Construire l'application

Pour commencer avec l'API du dictionnaire, nous avons besoin d'un ensemble de définitions de travail. Pour recréer ce scénario réel, nous avons opté pour un jeu de données réel. Nous avons pris le dump de définitions de Wikipedia et l'avons chargé dans Mongo. L'ensemble comprenait environ 700 000 mots, car nous n'avons importé que le dépotoir anglais. Chaque enregistrement (ou document) consiste en un mot, son type et sa signification. Vous pouvez en savoir plus sur le processus d'importation dans la import.txt fichier dans le référentiel.

Pour suivre le processus de développement, clonez le référentiel et vérifiez votre progression en basculant sur différents commits. Pour cloner le référentiel, utilisez la commande suivante:

$ git clone https://github.com/bhanuc/dictapi.git

Nous pouvons commencer par créer un serveur de base Koa:

var koa = require ('koa'); var app = koa (); app.use (function * (next) this.type = 'json'; this.status = 200; this.body = 'Bienvenue': 'Ceci est une application World Hello de niveau 2 !!';); if (! module.parent) app.listen (3000); console.log ('Hello World s'exécute sur http: // localhost: 3000 /'); 

Dans la première ligne, nous importons Koa et sauvegardons une instance dans la variable app. Ensuite, nous ajoutons un seul middleware à la ligne 5, qui est une fonction de générateur anonyme qui prend la variable suivante en tant que paramètre. Ici, nous définissons le type et le code de statut de la réponse, qui est également déterminé automatiquement, mais nous pouvons également les définir manuellement. Enfin, nous définissons le corps de la réponse. 

Étant donné que nous avons défini le corps dans notre premier middleware, cela marquera la fin de chaque cycle de requête et aucun autre middleware ne sera impliqué. Enfin, nous démarrons le serveur en appelant son écoute méthode et transmettez le numéro de port en tant que paramètre.

Nous pouvons démarrer le serveur en exécutant le script via:

$ npm installer koa $ node --harmony index.js

Vous pouvez directement atteindre cette étape en vous déplaçant 6858ae0:

$ git checkout 6858ae0

Ajout de capacités de routage

Le routage nous permet de rediriger différentes requêtes vers différentes fonctions en fonction du type de requête et de l'URL. Par exemple, nous pourrions vouloir répondre à /s'identifier différemment de s'inscrire. Cela peut être fait en ajoutant un middleware, qui vérifie manuellement l'URL de la demande reçue et exécute les fonctions correspondantes. Ou, au lieu d'écrire manuellement ce middleware, nous pouvons utiliser un middleware fait par la communauté, également appelé module middleware..

Pour ajouter une fonctionnalité de routage à notre application, nous utiliserons un module de communauté nommé Koa-routeur

Utiliser Koa-routeur, nous allons modifier le code existant pour le code ci-dessous:

var koa = require ('koa'); var app = koa (); var router = require ('koa-router'); var mount = require ('koa-mount'); var handler = function * (next) this.type = 'json'; this.status = 200; this.body = 'Welcome': 'Ceci est une application Hello World de niveau 2 !!'; ; var APIv1 = nouveau routeur (); APIv1.get ('/ all', gestionnaire); app.use (mount ('/ v1', APIv1.middleware ())); if (! module.parent) app.listen (3000); console.log ('Hello World s'exécute sur http: // localhost: 3000 /'); 

Ici, nous avons importé deux modules, où routeur magasins Koa-routeur et monter stocke le koa-mount module, nous permettant d'utiliser le routeur dans notre application Koa.

Sur la ligne 6, nous avons défini notre gestionnaire fonction, qui est la même fonction que précédemment, mais ici nous lui avons donné un nom. Sur la ligne 12, nous sauvegardons une instance du routeur dans APIv1, et sur la ligne 13, nous enregistrons notre gestionnaire pour tous les OBTENIR demandes en route /tout

Donc, toutes les requêtes sauf lorsqu'une requête get est envoyée à localhost: 3000 / tous retournera "non trouvé". Enfin sur la ligne 15, nous utilisons monter middleware, qui donne une fonction génératrice utilisable qui peut être alimentée app.use ().

Pour atteindre directement cette étape ou comparer votre application, exécutez la commande suivante dans le référentiel cloné:

$ git checkout 8f0d4e8

Avant de lancer notre application, nous devons maintenant installer Koa-routeur et koa-mount en utilisant npm. Nous observons qu’au fur et à mesure que la complexité de notre application augmente, le nombre de modules / dépendances augmente également.. 

Garder une trace de toutes les informations concernant le projet et les mettre à la disposition du npm, nous stockons toutes les informations dans package.json y compris toutes les dépendances. Vous pouvez créer package.json manuellement ou à l'aide d'une interface de ligne de commande interactive ouverte à l'aide de la commande $ npm init commander.

"name": "dictionnaire koa-api", "version": "0.0.1", "description": "application koa-api-dictionary", "main": "index", "auteur": " nom ":" Bhanu Pratap Chaudhary "," email ":" [email protected] "," référentiel ": " type ":" git "," url ":" https://github.com/bhanuc/ dictapi.git "," licence ":" MIT "," moteurs ": " noeud ":"> = 0.11.13 " 

Très minime package.json le fichier ressemble à celui ci-dessus. 

Une fois que package.json est présent, vous pouvez enregistrer la dépendance à l'aide de la commande suivante:

$ npm install  --enregistrer

Par exemple: Dans ce cas, nous installerons les modules à l’aide de la commande suivante pour enregistrer les dépendances dans package.json.

$ npm installer koa-routeur koa-mount --save

Maintenant, vous pouvez exécuter l'application en utilisant $ node --harmony index.js

Vous pouvez en savoir plus sur package.json ici.

Ajout d'itinéraires pour l'API du dictionnaire

Nous allons commencer par créer deux routes pour l'API, une pour obtenir un seul résultat dans une requête plus rapide et une seconde pour obtenir tous les mots correspondants (ce qui est plus lent pour la première fois).. 

Pour que les choses restent gérables, nous allons conserver toutes les fonctions de l’API dans un dossier séparé appelé api et un fichier appelé api.js, et l'importer plus tard dans notre principale index.js fichier.

var moine = require ('moine'); var wrap = require ('co-moine'); var db = moine ('localhost / mydb'); var words = wrap (db.get ('mots')); / ** * GET tous les résultats. * / exports.all = function * () if (this.request.query.word) var res = donne mots.find (word: this.request.query.word); this.body = res;  else this.response.status = 404; ; / ** * OBTENIR un seul résultat. * / exports.single = function * () if (this.request.query.word) var res = donne mots.findOne (word: this.request.query.word); this.body = res;  else this.response.status = 404; ;

Ici nous utilisons co-moine, qui agit comme un wrapper autour moine, Il est donc très facile pour nous d'interroger MongoDB à l'aide de générateurs situés à Koa. Ici, nous importons moine et co-moine, et connectez-vous à l'instance MongoDB sur la ligne 3. Nous appelons emballage() sur les collections, pour les rendre faciles à utiliser. 

Ensuite, nous ajoutons deux méthodes de générateur nommées tout et unique en tant que propriété du exportations variable afin qu'ils puissent être importés dans d'autres fichiers. Dans chacune des fonctions, nous vérifions d'abord le paramètre de requête 'mot'. Si présent, nous demandons le résultat ou nous répondons avec une erreur 404. 

Nous utilisons le rendement mot-clé pour attendre les résultats, comme indiqué dans le premier article, qui suspend l'exécution jusqu'à la réception du résultat. Sur la ligne 12, nous utilisons le trouver méthode, qui renvoie tous les mots correspondants, qui est stockée dans res et renvoyée par la suite. Sur la ligne 23, nous utilisons le findOne méthode disponible dans la collection, qui renvoie le premier résultat correspondant. 

Affectation de ces gestionnaires à des itinéraires

var koa = require ('koa'); var app = koa (); var router = require ('koa-router'); var mount = require ('koa-mount'); var api = require ('./ api / api.js'); var APIv1 = nouveau routeur (); APIv1.get ('/ all', api.all); APIv1.get ('/ single', api.single); app.use (mount ('/ v1', APIv1.middleware ())); if (! module.parent) app.listen (3000); console.log ('Dictapi est en cours d'exécution sur http: // localhost: 3000 /');

Ici nous importons des méthodes exportées de api.js et nous assignons des gestionnaires à OBTENIR itinéraires /tout  /unique et nous avons une API et une application entièrement fonctionnelles prêtes.

Pour exécuter l'application, il vous suffit d'installer le moine et co-moine modules en utilisant la commande ci-dessous. Assurez-vous également que vous avez une instance en cours d’exécution de MongoDB dans laquelle vous avez importé la collection présente dans le référentiel git à l’aide des instructions mentionnées dans import.txtweird.

$ npm installer moine co-moine --save

Vous pouvez maintenant exécuter l'application à l'aide de la commande suivante:

$ node --harmony index.js

Vous pouvez ouvrir le navigateur et les URL suivantes pour vérifier le fonctionnement de l'application. Il suffit de remplacer "nouveau" par le mot que vous souhaitez interroger.

  • http: // localhost: 3000 / v1 / all? word = new
  • http: // localhost: 3000 / v1 / single? word = new

Pour atteindre directement cette étape ou comparer votre application, exécutez la commande suivante dans le référentiel cloné:

$ git checkout f1076eb 

Traitement des erreurs dans Koa

En utilisant des middlewares en cascade, nous pouvons détecter les erreurs en utilisant le essayer / attraper mécanisme, car chaque middleware peut répondre en cédant à la fois en aval et en amont. Donc, si on ajoute un Essayer et attraper middleware au début de l'application, il interceptera toutes les erreurs rencontrées par la requête dans le reste du middleware, car ce sera le dernier middleware lors de la mise en amont. Ajout du code suivant sur la ligne 10 ou avant dans index.js devrait marcher.

app.use (function * (next) try return next; // passe l'exécution aux middlewares en aval catch (err) // exécuté uniquement lorsqu'une erreur se produit et qu'aucun autre middleware ne répond à la demande this.type = 'json'; // facultatif ici this.status = err.status || 500; this.body = 'error': 'L'application vient de passer à la folie, espérons que la NSA possède tous les journaux;)'; // déléguer l'erreur à l'application this.app.emit ('error', err, this); );

Ajout de la journalisation et de la limitation de débit à l'application

Le stockage des journaux est une partie essentielle d'une application moderne, car les journaux sont très utiles pour le débogage et la recherche de problèmes dans une application. Ils stockent également toutes les activités et peuvent donc être utilisés pour connaître les modèles d'activité des utilisateurs et d'autres modèles intéressants.. 

La limitation de débit est également devenue un élément essentiel des applications modernes, où il est important d'empêcher les spammeurs et les bots de gaspiller vos précieuses ressources de serveur et de les empêcher de supprimer votre API..

Il est assez facile d'ajouter la journalisation et la limitation de débit à notre application Koa. Nous allons utiliser deux modules de la communauté: koa-logger et koa-meilleur-limitant. Nous devons ajouter le code suivant à notre application:

var logger = require ('koa-logger'); var limite = require ('koa-better-ratelimit'); // Ajoute les lignes ci-dessous juste sous le middleware d'erreur. app.use (limite (durée: 1000 * 60 * 3, // 3 min max: 10, liste noire: [])); app.use (enregistreur ());

Ici, nous avons importé deux modules et les avons ajoutés en tant que middleware. L’enregistreur enregistrera chaque demande et imprimera le stdout du processus qui peut être facilement enregistré dans un fichier. Et limit middleware limite le nombre de demandes qu'un utilisateur donné peut demander dans un laps de temps donné (ici, dix demandes maximum en trois minutes). Vous pouvez aussi ajouter un tableau d’adresses IP qui seront placées sur une liste noire et leur demande ne sera pas traitée..

N'oubliez pas d'installer les modules avant d'utiliser le code en utilisant: 

$ npm installer koa-logger koa-better-ratelimit --save

Compresser le trafic

Un des moyens d’assurer une livraison plus rapide consiste à gzip votre réponse, ce qui est assez simple dans Koa. Pour compresser votre trafic sur Koa, vous pouvez utiliser le koa-compress module. 

Ici, les options peuvent être un objet vide ou peuvent être configurées selon les besoins..

var compress = require ('koa-compress'); var opts = filter: function (type_contenu) return /text/i.test(content_type), // filtre les demandes à compresser à l'aide du seuil d'expression régulière: 2048, // taille minimale à compresser flush: require ('zlib') .Z_SYNC_FLUSH;  // utilisez le code ci-dessous pour ajouter le middleware à l'application app.use (compress (opts)); 

Vous pouvez même désactiver la compression dans une demande en ajoutant le code suivant à un middleware:

this.compress = true;

N'oubliez pas d'installer Compresse avec npm

$ npm install compress --save 

Pour atteindre directement cette étape ou comparer votre application, exécutez la commande suivante dans le référentiel cloné:

Git Checkout 8f5b5a6 

Tests d'écriture

Le test devrait être une partie essentielle de tout code et devrait viser une couverture maximale du test. Dans cet article, nous allons écrire des tests pour les itinéraires accessibles depuis notre application. Nous utiliserons Supertest et Moka pour créer nos tests.. 

Nous allons stocker notre test dans test.js dans le api dossier. Dans les deux tests, nous décrivons d’abord notre test en lui donnant un nom plus lisible par l’homme. Après cela, nous allons passer une fonction anonyme qui décrit le comportement correct du test et prend un rappel qui contient le test réel. Dans chaque test, nous importons notre application, initions le serveur, décrivons le type de requête, l'URL et la requête, puis définissons le codage sur gzip. Enfin, nous vérifions la réponse si elle est correcte.

var request = require ('supertest'); var api = require ('… /index.js'); describe ('GET all', function () it ('devrait répondre avec tous les mots', function (done) var app = api; request (app.listen ()) .get ('/ v1 / all') .query (word: 'new') .set ('Accept-Encoding', 'gzip') .expect ('Content-Type', / json /) .expect (200) .end (done);) ) décris ('GET / v1 / single', function () it ('devrait répondre avec un seul résultat', function (done) var app = api; request (app.listen ()) .get ('/ v1 / single ') .query (word:' new ') .set (' Accept-Encoding ',' gzip ') .expect (200) .expect (' Content-Type ', / json /) .end ( function (err, res) if (err) renvoie err; else if (! ('_ id' dans res.body)) renvoie "id manquant"; if (! ("mot" dans res.body)) lance un nouveau Erreur ("mot manquant"); done (););))

Pour exécuter notre test, nous allons faire un Makefile:

test: @ NODE_ENV = test ./node_modules/.bin/mocha \ --require devrait \ --reporter nyan \ --harmony \ --bail \ api / test.js .PHONY: test

Ici, nous avons configuré le reporter (chat nyan) et le framework de test (moka). Notez que l'importation doit ajouter --harmonie activer le mode ES6. Enfin, nous spécifions également l'emplacement de tous les tests. UNE Makefile peut être configuré pour tester sans fin votre application.

Maintenant, pour tester votre application, utilisez simplement la commande suivante dans le répertoire principal de l'application. 

$ make test

Rappelez-vous simplement d'installer les modules de test (mocha, devrait, supertest) avant de tester, en utilisant la commande ci-dessous: 

$ npm installer mocha devrait mocha --save-dev 

Courir en production

Pour exécuter nos applications en production, nous allons utiliser PM2, qui est un moniteur de processus de nœud utile. Nous devrions désactiver l'application de journalisation pendant la production; il peut être automatisé en utilisant des variables d'environnement.

Pour installer PM2, entrez la commande suivante dans le terminal

$ npm install pm2 -g 

Et notre application peut être lancée à l'aide de la commande suivante:

$ pm2 start index.js --node-args = "- harmonie" 

Maintenant, même si notre application se bloque, elle redémarrera automatiquement et vous pourrez dormir profondément. 

Conclusion

Koa est un middleware léger et expressif pour Node.js qui rend le processus d’écriture d’applications Web et d’API plus agréable.. 

Il vous permet de tirer parti d'une multitude de modules de communauté pour étendre les fonctionnalités de votre application et simplifier toutes les tâches banales, faisant du développement Web une activité amusante.. 

N'hésitez pas à laisser des commentaires, des questions ou d'autres informations dans le champ ci-dessous.