Vă întrebați vreodată ce se întâmplă în toate middleware-urile Express.js pe care le adăugați la aplicația dvs. web? De fapt, este destul de impresionant ce fel de funcționalitate puteți adăuga la aplicațiile dvs. cu o singură linie de cod sau câteva:

scrie

Ultimele trei linii de mai sus tratează destul de puțin funcționalitatea aplicației web pentru noi. Primul apel app.use () spune Express unde se află fișierele noastre statice și cum să le expunem, middleware-ul cookieParser („secret”) gestionează toate analizele cookie-urilor (cu criptare), iar ultimul gzip comprimă automat toate HTTP-urile noastre datele corpului. Nu este rău pentru doar trei linii de cod.

Aceste middleware sunt destul de tipice în aplicația dvs. web medie, dar puteți găsi unele care fac mai mult decât simpla compresie de date standard sau analiza cookie-urilor. Luați aceste exemple, de exemplu:

  • cască: ajută la securizarea aplicației dvs. prin setarea diferitelor antete HTTP
  • express-simple-cdn: utilizați cu ușurință un CDN pentru activele statice
  • join-io: Alăturați fișierele din mers pentru a reduce numărul de solicitări HTTP
  • pașaport: adaugă autentificarea utilizatorului la rutele selectate

Iată o listă mult mai largă de middleware pe care ați putea dori să o folosiți.

Acum că ați văzut câteva exemple, iată aproape tot ce puteți face cu el:

  • Executați orice cod, inclusiv cod asincron
  • Efectuați modificări sau adăugiri la obiectele de solicitare și răspuns
  • Încheiați ciclul de solicitare-răspuns
  • Apelați următorul middleware din stivă

Cu posibilitățile nesfârșite, sunt sigur că aveți câteva idei proprii pe care ați dori să le creați, așa că în restul acestui articol vă voi arăta cum să vă scrieți propriul middleware. Există câteva tipuri diferite de middleware pe care le puteți scrie (aplicație, router, gestionarea erorilor etc.), dar în acest articol ne vom concentra doar la nivelul aplicației.

Cele elementare

Middleware poate fi gândit aproape ca și cum ar fi un traseu Express. Aceștia iau aceiași parametri și totul, dar spre deosebire de rutele normale, nu vi se cere să furnizați o cale URL pentru middleware. Cele mai mari două diferențe sunt modul în care este tratată calea și când este apelată.

Calea furnizată este tratată ca un prefix, deci dacă ați avut ceva de genul app.use ('/ api',.), atunci middleware-ul dvs. va rula dacă/api este apelat și dacă/api/users este apelat. Acest lucru este diferit de traseele în care calea trebuie să fie o potrivire exactă.

Calea URL-ului poate fi omisă din apelul app.use () dacă doriți ca codul dvs. să ruleze pentru toate cererile, altfel puteți specifica o cale și să vă rulați codul numai atunci când ruta respectivă (și toate subrutele sale) este solicitat. De exemplu, acest lucru ar putea fi util pentru adăugarea autentificării doar la câteva rute date.

Un middleware simplu ar putea arăta astfel:

Întrucât un gestionar de traseu arată astfel:

Vedea? Practic sunt același lucru, așa că scrierea acestor funcții ar trebui să vă fie destul de familiară.

Parametrii utilizați sunt:

  • cerere: un obiect care conține toate informațiile relevante despre cerere. Aceasta poate fi orice, de la adresa URL solicitată către corpul unei cereri POST la adresa IP a utilizatorului.
  • res: Acesta este obiectul de răspuns, care este utilizat pentru a trimite date înapoi utilizatorului pentru cererea dată. Puteți utiliza acest lucru pentru a trimite înapoi un cod de răspuns HTTP 404 sau pentru a trimite înapoi HTML redat prin res.render () .
  • următor: Și, în sfârșit, următorul parametru este un callback pentru a spune Express când middleware-ul nostru a terminat. Dacă faceți IO (cum ar fi apeluri la baze de date) sau calcule grele, atunci va trebui probabil să faceți funcția asincronă pentru a preveni blocarea firului principal de execuție, caz în care va trebui să utilizați următorul .

Este demn de remarcat faptul că, dacă middleware-ul dvs. nu încheie ciclul de solicitare-răspuns cu res.end (.) Atunci tu trebuie sa call next () pentru a trece controlul către următorul middleware. Dacă nu, cererea va fi lăsată suspendată și va expira.

Un exemplu

În acest exemplu, vom crea middleware care vă ajută să traduceți automat text între limbi. Totuși, acesta nu este un modul i18n tipic, vom folosi în schimb Google Translate.

Să presupunem că ați creat o aplicație de chat care vă permite să vorbiți cu oameni din întreaga lume și, pentru a o simplifica, aveți nevoie ca textul să fie tradus automat. În acest caz de utilizare, majoritatea modulelor i18n nu ar funcționa deoarece trebuie să traduceți în prealabil toate șirurile, ceea ce nu putem face din moment ce avem de-a face cu introducerea utilizatorului.

Sigur, ați putea gestiona traducerea în fiecare dintre rutele dvs. Express sau ați putea să o gestionați în middleware, care vă păstrează codul de rută mai curat și vă împiedică să uitați să adăugați traducere la fiecare rută care are nevoie de ea.

Șirurile (mesajele utilizatorului) vin printr-un API REST, așa că va trebui să verificăm toate corpurile rutelor API pentru a traduce textul. Toate șirurile salvate în baza de date în apelurile POST vor fi păstrate în limbile lor native, dar toate șirurile preluate din baza de date cu apeluri GET vor fi traduse în limba specificată în antetul HTTP Accept-Language care însoțește cererea utilizatorului.

M-am gândit că nu vom transforma toate mesajele din baza de date în aceeași limbă, deoarece va trebui apoi să traducem unele dintre ele de două ori, ceea ce degradează calitatea traducerii.

În primul rând, să scriem o funcție simplă pentru a apela API-ul Google Translate:

Apoi vom folosi acea funcție în codul nostru middleware, care este exportat în modules.export pentru utilizare de către aplicație.

NOTĂ: Nu este așa cum modificați un corp de răspuns. Îl simplific doar din motive de scurtă durată. Dacă doriți să vedeți cum să modificați efectiv corpul, verificați middleware-ul de compresie, care îl face corect. Trebuie să proxy funcțiile res.write și res.end, ceea ce nu am făcut pentru că ar fi doar o distragere a atenției de la conceptele pe care încerc să le arăt aici.

Și, în cele din urmă, aplicăm middleware-ul aplicației noastre. Asigurați-vă că apelați funcția app.use după ce ați declarat deja rutele. Ordinea în care este numită este ordinea în care rulează fiecare funcție.

De asemenea, asigurați-vă că apelați next () în fiecare dintre traseele dvs./api, altfel middleware-ul nu va rula.

Și asta este tot ce există. Orice șir returnat în corpul de răspuns care este o limbă diferită de ceea ce acceptă utilizatorul va fi tradus de Google Translate, care detectează în ce limbă se află textul sursă.

Deci, dacă răspunsul nostru a început să arate așa.

. iar utilizatorul acceptă numai swahili, apoi după executarea middleware-ului vom primi o traducere finală care arată astfel:

Concluzie

Deși poate părea intimidant, middleware-ul este foarte ușor de creat în Express. Îl puteți folosi pentru aproape orice, indiferent cât de simplu sau complex este.

Doar asigurați-vă că efectuați o căutare rapidă pe npm pentru orice încercați să faceți, deoarece multe tone de cod sunt deja acolo. Sunt sigur că există deja un pachet care face ceea ce face codul meu de traducere (și probabil mult mai bine și el).

Aveți idei pentru middleware de creat sau cum să îmbunătățiți exemplul meu de mai sus? Spuneți-ne în comentarii!