Introducere în Generatoare & Koa.js Partea 2

Ce veți crea

Bine ați venit în a doua parte a seriei noastre despre generatoare și Koa. Dacă ai pierdut-o, poți citi secțiunea 1 aici. Înainte de a începe procesul de dezvoltare, asigurați-vă că ați instalat Node.js 0.11.9 sau o versiune ulterioară.

În această parte, vom crea un dicționar API folosind Koa.js și veți afla despre rutarea, comprimarea, înregistrarea, limitarea ratei și tratarea erorilor în Koa.js. Vom folosi de asemenea Mongo ca datastore și vom afla în scurt despre importul de date în Mongo și despre ușurința care vine cu interogarea în Koa. În sfârșit, vom examina depanarea aplicațiilor Koa.

Înțelegând Koa

Koa are schimbări radicale construite sub capota lui, care leagă bunătatea generatorului ES6. În afară de schimbarea fluxului de control, Koa introduce propriile sale obiecte personalizate, cum ar fi acest, aceasta cerere, și this.response, care funcționează convenabil ca un strat de sintactică-zahăr construit pe partea de sus a obiectelor Node și res, oferindu-vă acces la diverse metode de conveniență și getters / setters. 

În afară de confort, Koa, de asemenea, curăță middleware-ul, care, în Express, se baza pe hack-uri urâte care adesea au modificat obiectele de bază. De asemenea, oferă o mai bună manipulare a fluxului.

Așteaptă, ce este un middleware?

Un middleware este o funcție pluggable care adaugă sau elimină o anumită piesă de funcționalitate făcând ceva lucru în obiectele de cerere / răspuns în Node.js.

Produsele Middleware din Koa

Un middleware Koa este în esență o funcție a generatorului care returnează o funcție a generatorului și acceptă un alt generator. De obicei, o aplicație are o serie de middleware care sunt difuzate pentru fiecare solicitare. 

De asemenea, un middleware trebuie să cedeze următorului middleware "în aval", dacă acesta este rulat de un "middleware din amonte". Vom discuta mai multe despre aceasta în secțiunea de tratare a erorilor.

Clădire Middleware

Doar un ultim lucru: Pentru a adăuga un middleware la aplicația dvs. Koa, vom folosi koa.use () și furnizează funcția middleware drept argument. Exemplu: app.use (koa-logger) adaugă koa-logger la lista de middleware pe care o folosește aplicația noastră.

Construirea aplicației

Pentru a începe cu dicționarul API, avem nevoie de un set de definiții de lucru. Pentru a recrea acest scenariu real, am decis să mergem cu un set real de date. Am luat discul de definire de pe Wikipedia și l-am încărcat în Mongo. Setul a constat din aproximativ 700.000 de cuvinte, deoarece am importat numai dumpurile englezești. Fiecare înregistrare (sau document) constă dintr-un cuvânt, de tipul acestuia și de semnificația acestuia. Puteți citi mai multe despre procesul de import în import.txt fișier în depozit.

Pentru a vă deplasa de-a lungul procesului de dezvoltare, clonați depozitul și verificați progresul prin trecerea la comitete diferite. Pentru a clona repo-ul, utilizați următoarea comandă:

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

Putem începe prin crearea unui server de bază Koa:

var koa = necesită ("koa"); var app = koa (); app.use (funcția * (următoarea) this.type = 'json'; this.status = 200; this.body = 'Bun venit': 'Aceasta este o aplicație de nivel 2 Hello World !!';); dacă (! module.parent) app.listen (3000); console.log ("Hello World se execută pe http: // localhost: 3000 / '); 

În prima linie, importăm Koa și salvăm o instanță în variabila aplicației. Apoi adăugăm un singur middleware pe linia 5, care este o funcție generatoare anonimă care ia variabila următoare ca parametru. Aici, setăm tipul și codul de stare al răspunsului, care este, de asemenea, determinat automat, dar putem, de asemenea, să le setăm manual. Apoi, în final, am stabilit corpul răspunsului. 

Deoarece am pus corpul în primul nostru middleware, acesta va marca sfârșitul fiecărui ciclu de solicitare și nu va fi implicat niciun alt middleware. În cele din urmă, pornim serverul apelând la acesta asculta și transmiteți numărul portului ca parametru.

Putem porni serverul rulând scriptul prin:

$ npm instalează koa $ node --harmony index.js

Puteți ajunge direct la această etapă prin mișcarea de a vă angaja 6858ae0:

$ git checkout 6858ae0

Adăugarea capabilităților de rutare

Rutarea ne permite să redirecționăm diferite cereri către diferite funcții pe baza tipului de solicitare și a adresei URL. De exemplu, am putea dori să răspundem /Logare altfel decât Inscrie-te. Acest lucru se poate face prin adăugarea unui middleware, care verifică manual adresa URL a cererii primite și execută funcțiile corespunzătoare. Sau, în loc să scrie manual acest middleware, putem folosi un middleware comunitar, cunoscut și ca modul middleware.

Pentru a adăuga capacitatea de rutare aplicației noastre, vom folosi un modul comunitar numit koa-router

A folosi koa-router, vom modifica codul existent la codul de mai jos:

var koa = necesită ("koa"); var app = koa (); var router = necesită ("koa-router"); var mount = necesită ('koa-mount'); var handler = funcție * (următoarea) this.type = 'json'; this.status = 200; this.body = 'Bun venit': 'Aceasta este o aplicație de nivel 2 Hello World!'; ; var APIv1 = router nou (); APIv1.get ('/ tot', handler); app.use (mount ('/ v1', APIv1.middleware ())); dacă (! module.parent) app.listen (3000); console.log ("Hello World se execută pe http: // localhost: 3000 / '); 

Aici am importat două module, unde router magazine koa-router și montură stochează koa-mount modul, care ne permite să folosim router-ul în aplicația noastră Koa.

Pe linia 6, ne-am definit manipulant funcția, care este aceeași funcție ca înainte, dar aici i-am dat un nume. Pe linia 12, salvăm o instanță a routerului în APIv1, iar pe linia 13 ne înregistrăm pe handler pentru toate OBȚINE cereri pe traseu /toate

Deci, toate cererile, cu excepția cazului în care este trimisă o cerere de solicitare localhost: 3000 / toate se va întoarce "nu a fost găsit". În cele din urmă pe linia 15, vom folosi montură middleware, care oferă o funcție generabilă utilizabilă care poate fi alimentată app.use ().

Pentru a ajunge direct la acest pas sau pentru a compara cererea dvs., executați următoarea comandă în repo clonat:

$ git checkout 8f0d4e8

Înainte de a ne rula aplicația, acum trebuie să instalăm koa-router și koa-mount utilizând NPM. Observăm că, pe măsură ce crește complexitatea cererii noastre, crește și numărul de module / dependențe. 

Pentru a urmări toate informațiile despre proiect și a le pune la dispoziție NPM, stocăm toate informațiile în package.json inclusiv toate dependențele. Puteți crea pachetul package.json manual sau utilizând o interfață de linie de comandă interactivă care este deschisă utilizând $ npm init comanda.

"nume": "koa-api-dicționar", "versiune": "0.0.1", "descriere" nume ":" Bhanu Pratap Chaudhary "," email ":" [email protected] "," depozit ": " type ":" git "," url ":" https://github.com/bhanuc/ dictapi.git "," licență ":" MIT "," motoare ": " nod ":"> = 0.11.13 " 

Un foarte minim package.json fișierul arată ca cel de mai sus. 

O singura data package.json este prezent, puteți salva dependența utilizând următoarea comandă:

$ npm install  --Salvați

De exemplu: În acest caz, vom instala modulele folosind următoarea comandă pentru a salva dependențele package.json.

$ npm instalare koa-router koa-mount - salvează

Acum puteți rula aplicația utilizând $ node --harmony index.js

Puteți citi mai multe despre package.json aici.

Adăugarea rutelor pentru API-ul de dicționar

Vom începe prin crearea a două rute pentru API, unul pentru obținerea unui singur rezultat într-o interogare mai rapidă și o secundă pentru a obține toate cuvintele potrivite (ceea ce este mai lent pentru prima dată). 

Pentru a păstra lucrurile ușor de gestionat, vom păstra toate funcțiile API într-un director separat numit api și un fișier numit api.js, și să-l importem mai târziu în principal index.js fişier.

var călugăr = cer ("călugăr"); var wrap = necesită ("co-monk"); var db = călugăr ("localhost / mydb"); var cuvinte = wrap (db.get ("cuvinte")); / ** * GET toate rezultatele. * / exports.all = funcția * () if (this.request.query.word) var res = randamentul words.find (cuvânt: this.request.query.word); this.body = res;  altfel this.response.status = 404; ; / ** * OBȚINE un singur rezultat. * / exports.single = funcție * () if (this.request.query.word) var res = randament words.findOne (cuvânt: this.request.query.word); this.body = res;  altfel this.response.status = 404; ;

Aici folosim co-călugăr, care acționează în jurul ei călugăr, ceea ce face foarte ușor pentru noi să interogăm MongoDB folosind generatoare în Koa. Aici, importăm călugăr și co-călugăr, și conectați-vă la instanța MongoDB pe linia 3. Sunăm înfășurați () pe colecții, pentru a le face prietenoase cu generatorul. 

Apoi adăugăm două metode de generare numite toate și singur ca proprietate a exporturi astfel încât să poată fi importate în alte fișiere. În fiecare dintre funcții, mai întâi verificăm parametrul de interogare "cuvânt". Dacă este prezent, vom interoga rezultatul sau altceva vom răspunde cu o eroare de 404. 

Noi folosim Randament cuvântul cheie să aștepte rezultatele așa cum au fost discutate în primul articol, care întrerupe execuția până când rezultatul este primit. Pe linia 12, folosim găsi , care returnează toate cuvintele potrivite, care sunt stocate în res și apoi trimise înapoi. Pe linia 23, folosim găsește una metoda disponibilă pentru colectare, care returnează primul rezultat de potrivire. 

Atribuirea acestor manipulanți pe rute

var koa = necesită ("koa"); var app = koa (); var router = necesită ("koa-router"); var mount = necesită ('koa-mount'); var api = cer ('./ api / api.js'); var APIv1 = router nou (); APIv1.get ('/ toate', api.all); APIv1.get ('/ single', api.single); app.use (mount ('/ v1', APIv1.middleware ())); dacă (! module.parent) app.listen (3000); console.log ("Dictapi rulează pe http: // localhost: 3000 / ');

Aici vom importa metode exportate api.js și le-am atribuit agenți de manipulare OBȚINE rute /toate  /singur și avem un API pe deplin funcțional și gata de utilizare.

Pentru a rula aplicația, trebuie doar să instalați aplicația călugăr și co-călugăr module folosind comanda de mai jos. De asemenea, asigurați-vă că aveți o instanță în execuție a MongoDB în care ați importat colecția prezentă în depozitul git folosind instrucțiunile menționate în import.txtweird.

$ npm instala călugăr co-monk - salvează

Acum puteți rula aplicația utilizând următoarea comandă:

$ node --harmony index.js

Puteți deschide browserul și puteți deschide următoarele adrese URL pentru a verifica funcționarea aplicației. Doar înlocuiți "nou" cu cuvântul pe care doriți să îl interogați.

  • http: // localhost: 3000 / v1 / toate cuvânt = nou
  • http: // localhost: 3000 / v1 / singur cuvânt = nou

Pentru a ajunge direct la acest pas sau pentru a compara cererea dvs., executați următoarea comandă în repo clonat:

$ git checkout f1076eb 

Efectuarea erorilor în Koa

Folosind middlewares cascading, putem detecta erori folosind încearcă să prinzi mecanism, deoarece fiecare middleware poate răspunde în timp ce cedează în aval, precum și în amonte. Deci, dacă adăugăm a Încercați și prindeți middleware la începutul aplicației, va prinde toate erorile întâmpinate de cerere în restul middleware-ului, deoarece acesta va fi ultimul middleware în timpul upstreaming-ului. Adăugând următorul cod pe linia 10 sau înainte în index.js ar trebui să funcționeze.

app.use (funcția * (următoarea) try randamentul următor; // transmite execuția în middlewares downstream captură (err) // executată numai atunci când apare o eroare și nici un alt middleware nu răspunde cererii this.type = 'json'; // opțional aici this.status = err.status || 500; this.body = 'error': 'Aplicația tocmai a mers în picioare, sperăm că NSA are toate jurnalele;)'; // delega eroarea înapoi la aplicația this.app.emit ('error', err, this); );

Adăugarea înregistrării și limitarea ratei la aplicație

Stocarea jurnalelor este o parte esențială a unei aplicații moderne, deoarece jurnalele sunt foarte utile în depanarea și găsirea problemelor dintr-o aplicație. De asemenea, stochează toate activitățile și astfel pot fi folosite pentru a afla modelele de activitate ale utilizatorilor și alte modele interesante. 

Limitarea ratelor a devenit, de asemenea, o parte esențială a aplicațiilor moderne, în care este important să opriți spammerii și roboții de la pierderea resurselor prețioase ale serverului și de a le împiedica să vă răsturnați API-ul.

Este destul de ușor să adăugăm logarea și limitarea ratei la aplicația noastră Koa. Vom folosi două module comunitare: koa-logger și koa-o mai bună rată de limitare a. Trebuie să adăugăm următorul cod în aplicația noastră:

var logger = necesită ("koa-logger"); var limit = necesită ("koa-better-ratelimit"); // Adăugați liniile de mai jos doar sub middleware de eroare. app.use (limită (durată: 1000 * 60 * 3, // 3 min max: 10, lista neagră: [])); app.use (logger ());

Aici am importat două module și le-am adăugat ca middleware. Loggerul va înregistra fiecare cerere și va fi imprimat în stdout a procesului care poate fi ușor salvat într-un fișier. Și limitarea middleware limitează numărul de cereri pe care un utilizator dat le poate solicita într-un anumit interval de timp (aici este maximum zece cereri în trei minute). De asemenea, puteți adăuga o serie de adrese IP care vor fi listate pe negru și cererea lor nu va fi procesată.

Nu uitați să instalați modulele înainte de a utiliza codul folosind: 

$ npm instalare koa-logger koa-better-ratelimit - salvați

Comprimarea traficului

Una dintre modalitățile de a asigura o livrare mai rapidă este să vă gzip răspunsul, ceea ce este destul de simplu în Koa. Pentru a vă comprima traficul în Koa, puteți utiliza koa-compresa modul. 

Aici opțiunile pot fi un obiect gol sau pot fi configurate conform cerințelor.

var compress = necesită ("koa-compress"); var opts = filtru: functie (content_type) retur /text/i.test(content_type), // filtrarea cererilor de comprimat folosind pragul regex: 2048, // dimensiune minima pentru a comprima flush: require ('zlib') .Z_SYNC_FLUSH;  // utilizați codul de mai jos pentru a adăuga middleware-ul la aplicația app.use (compress (opts)); 

Puteți chiar să dezactivați comprimarea într-o solicitare prin adăugarea următorului cod la un middleware:

this.compress = true;

Nu uitați să instalați compresorul folosind NPM

$ npm instalează compresia - salvează 

Pentru a ajunge direct la acest pas sau pentru a compara cererea dvs., executați următoarea comandă în repo clonat:

git checkout 8f5b5a6 

Scrierea testelor

Testarea ar trebui să fie o parte esențială a întregului cod și ar trebui să fie vizată o acoperire maximă a testelor. În acest articol, vom scrie teste pentru rutele accesibile din aplicația noastră. Vom folosi supertest și Mocha pentru a crea testele noastre. 

Vom stoca testul nostru test.js în api pliant. În ambele teste, mai întâi descriem testul nostru, oferindu-i un nume mai ușor de citit de om. După aceasta, vom trece o funcție anonimă care descrie comportamentul corect al testului și va efectua un apel invers care conține testul real. În fiecare test, importăm aplicația noastră, inițiază serverul, descrie tipul de solicitare, adresa URL și interogarea și apoi setați codificarea la gzip. În cele din urmă, verificăm răspunsul dacă este corect.

var request = solicită ('supertest'); var api = cer ('... / index.js'); descrie ('GET ALL', functie () it ('ar trebui sa raspunda cu toate cuvintele', function (done) var app = api; request (app.listen ()) .get ('/ v1 / all') .query (cuvânt: 'new') .set ('Accept-Encoding', 'gzip') .expect ('Content-Type', / json / ) descrie ('GET / v1 / singură', funcția () it (ar trebui să răspundă cu un singur rezultat ' v1 / single) .query (cuvânt: 'new') .set ('Accept-Encoding', 'gzip') .expect (200) (if (err, res) if (err) arunca err; altceva if (! ('id' in res.body) Eroare ("cuvânt lipsă"); done (););))

Pentru a face testul nostru, vom face o Makefile:

test: @ NODE_ENV = test ./node_modules/.bin/mocha \ --require ar trebui să \ --report nyan \ --armonia \ --bail \ api / test.js .FONY: test

Aici, am configurat reporterul (pisica nyan) și cadrul de testare (mocha). Rețineți că trebuie adăugat importul --armonie pentru a activa modul ES6. În cele din urmă, specificăm locația tuturor testelor. A Makefile poate fi configurat pentru testarea nesfârșită a aplicației dvs..

Acum, pentru a testa aplicația, utilizați următoarea comandă în directorul principal al aplicației. 

$ face test

Nu uitați să instalați module de testare (mocha, should, supertest) înainte de testare, utilizând comanda de mai jos: 

$ npm install mocha ar trebui să mocha - save-dev 

A alerga în producție

Pentru a rula aplicațiile noastre în producție, vom folosi PM2, care este un monitor de proces Nod util. Ar trebui să dezactivați aplicația logger în timpul producției; acesta poate fi automatizat folosind variabile de mediu.

Pentru a instala PM2, introduceți următoarea comandă în terminal

$ npm instala pm2 -g 

Aplicația noastră poate fi lansată utilizând următoarea comandă:

$ pm2 începe index.js --node-args = "- armonie" 

Acum, chiar dacă aplicația noastră se blochează, va reporni automat și puteți dormi fără probleme. 

Concluzie

Koa este un middleware ușor și expresiv pentru Node.js care face procesul de scriere a aplicațiilor web și API mai plăcut. 

Acesta vă permite să utilizați o multitudine de module comunitare pentru a extinde funcționalitatea aplicației dvs. și pentru a simplifica toate sarcinile lumești, făcând ca dezvoltarea web să devină o activitate distractivă. 

Vă rugăm să nu ezitați să lăsați orice comentarii, întrebări sau alte informații în câmpul de mai jos.


Cod