Introducere
Când încerci să înveți despre web
dezvoltare, descoperim de obicei că front-end-ul este semnificativ mai accesibil decât back-end-ul. Există multe motive pentru aceasta, în special sentimentul de feedback instantaneu care vine din schimbarea unui anumit element al unei pagini din cod și observarea modificării aplicate site-ului web. Acest feedback este adesea util pentru începători, deoarece le permite să își ajusteze codul și să învețe din greșelile lor. Din păcate, nu este cazul backend-ului: de multe ori, o cantitate semnificativă de muncă este dedicată instalării în avans a mediului și instalării dependențelor necesare pentru a obține un mesaj simplu „Hello World” să apară pe terminal., se realizează în mod constant multe progrese în comunitatea open-source în ceea ce privește facilitarea procesului de dezvoltare a cadrelor, iar îmbunătățirea experienței dezvoltatorului NodeJ este un bun exemplu în acest sens cod în Javascript convenabil și oferă o varietate de instrumente și caracteristici încorporate care îl diferențiază de concurenții săi. În acest articol, vom explora NodeJs și ecosistemul său, cu o abordare practică, construind un proiect complet funcțional.
Ce vom construi?
Aplicațiile ToDo sunt un proiect de bază pentru începătorii care învață dezvoltarea front-end. Acesta este motivul pentru care am decis să construim un API pentru lista de activități. Acest lucru ne va permite să adăugăm persistența datelor la interfața noastră și ne va oferi posibilitatea de a manipula aceste date (prin adăugarea, actualizarea, ștergerea tuturor etc.).
Codul final poate fi găsit aici.
Instrumentele noastre
Vom folosi o stivă tehnologică simplificată pentru acest proiect. Poate fi considerată o versiune minimă a multor instrumente pe care le veți găsi în proiectele din viața reală, motivul fiind că ideile de nivel superior sunt aceleași. Detaliile implementării și alegerea unui anumit instrument în detrimentul altuia nu sunt importante pentru a începe.
-
NodeJs, așa cum am menționat, este unul dintre cele mai populare cadre Javascript pentru construirea de aplicații pe server.
-
ExpressJs este un cadru Javascript minim folosit pe lângă NodeJS. Accelerează procesul de dezvoltare prin utilizarea multor funcții încorporate. Este, de asemenea, folosit ca o modalitate de a standardiza practicile de dezvoltare în proiectele NodeJS pentru a facilita utilizarea acestuia de către ingineri.
-
LowDB este o bază de date simplă în memorie. Simplitatea sa ne permite să arătăm cum să interacționăm cu o bază de date într-un proiect NodeJs, fără a ne ocupa de subiecte mai avansate, cum ar fi implementările și configurațiile.
Acum că am identificat toate instrumentele pe care le vom folosi, să trecem la tastaturile noastre și să începem să codificăm!
Instalare
Node este disponibil pe toate platformele. Toate ghidurile de instalare pot fi găsite pe site-ul oficial. Utilizatorii Windows ar trebui să se asigure că adaugă nodul calea către variabilele de mediu, astfel încât să poată fi utilizat pe linia de comandă.
De asemenea, vom avea nevoie de instalat npm. Npm este managerul de pachete standard pentru NodeJs. Ne va permite să ne gestionăm dependențele de proiect. Ghidul de instalare poate fi găsit aici.
Inițializarea proiectului
Accesați linkul și clonați proiectul de pornire:
Acesta este un depozit de pornire simplu pentru proiectul nostru. Conține toate dependențele pe care le vom folosi împreună cu structura fișierului de proiect. Vom explica fiecare element odată ajuns. Deschideți terminalul, navigați la calea proiectului și executați comanda:
npm install
Aceasta va instala toate dependențele proiectului specificate în fișierul package.json. package.json este fișierul găsit la rădăcina oricărui proiect Javascript/NodeJs, conține metadate despre acesta din urmă și este folosit pentru a gestiona toate dependențele, scripturile și versiunile de proiect.
După ce toate dependențele sunt instalate, putem porni aplicația noastră:
npm run start
„start” este un script pe care l-am specificat în pachet. fișier json. Specifică fișierul de intrare în aplicația noastră, care în cazul nostru este app.js.
Următorul mesaj ar trebui să apară acum pe terminalul dvs.:
Aceasta înseamnă că serverul nostru a pornit cu succes și ascultă orice solicitare trimisă la portul 3000. Să ne uităm la app.js și să explicăm ce se întâmplă aici:
App.js este fișierul nostru de intrare în proiect (și singurul în acest moment). Instanțiem o aplicație expres numită app, specificăm că toate cererile care au metoda http „GET” și sub-calea „/” vor fi gestionate de această rută, trecem o funcție numită middleware, care preia obiectul cerere și răspuns ca parametrii. Acest lucru este crucial, deoarece cererea conține toate informațiile necesare pentru ca aceasta să fie tratată (parametri, corpul cererii, anteturile cererii etc.), iar obiectul răspuns este cel care va fi returnat clientului. Începem prin a trimite mesajul „Bună ziua, lume”. După aceea, facem ca aplicația noastră să asculte orice solicitări primite către portul specificat (în cazul nostru 3000) și înregistrăm mesajul „Ascultând portul 3000” pentru a indica faptul că aplicația noastră este în funcțiune și gata să primească cereri.
Deschideți terminalul și în bara de linkuri tastați „localhost:3000/” și apăsați Enter. Aceasta este calea specificată pe care o putem folosi pentru a ajunge la serverul nostru local. Veți primi următorul mesaj:
Configurarea bazei de date
Lowdb este o bază de date open-source care este ușor de utilizat și nu necesită o configurare specifică. Ideea generală din spatele acestuia este de a stoca toate datele într-un fișier JSON local. După ce LowDB este instalat (ceea ce a fost făcut când am instalat toate dependențele), putem adăuga următorul cod la db.js:
Acest cod este destul de similar cu cel găsit în documentația oficială LowDB. L-am ajustat puțin pentru propriul nostru caz de utilizare. Să explicăm rând cu rând:
Primele rânduri sunt pentru importarea dependențelor necesare. „join” este o funcție de utilitate disponibilă în modulul „cale”. Este unul dintre modulele de bază ale NodeJs care oferă o mulțime de metode pentru a trata și gestiona căile. „Low” și „JSONFile” sunt cele două clase expuse de LowDB. Primul creează instanța fișierului json care va conține datele noastre. Al doilea creează instanța actuală a bazei de date care va acționa asupra acesteia. În cele din urmă, „lodash” este una dintre cele mai utilizate biblioteci javascript, oferind o mare varietate de funcții utilitare pentru sarcinile obișnuite de programare. Îl adăugăm la instanța noastră de bază de date pentru a ne permite să folosim metodele sale avansate pentru a ne gestiona datele.
Mai întâi, specificăm calea fișierului db.json. Este fișierul care va conține datele noastre și va fi transmis către LowDB. Dacă fișierul nu este găsit la calea specificată, LowDB va crea una.
Apoi trecem calea fișierului adaptorului LowDB și o transmitem noii instanțe de bază de date LowDB. Variabila „db” poate fi apoi utilizată pentru a comunica cu baza noastră de date. Odată ce instanța bazei de date este creată, citim din fișierul json utilizând db.read(). Aceasta va seta câmpul „date” în instanța bazei de date, astfel încât să putem accesa conținutul bazei de date. Observați că am precedat această linie cu „așteaptă”. Aceasta este pentru a specifica că această instrucțiune poate dura un timp necunoscut pentru a se rezolva și că procesul NodeJs trebuie să aștepte execuția sa înainte de a continua cu restul codului. Facem acest lucru deoarece operația de citire necesită acces de memorie la fișierul specificat, iar timpul de executare a acestui tip de operație depinde de specificațiile mașinii dumneavoastră.
Acum că avem acces la câmpul de date, îl setăm ca un obiect care conține o matrice goală de postări sau, mai degrabă, verificăm dacă fișierul conține date anterioare și setăm matricea goală dacă nu este cazul.
În cele din urmă, executăm db.write() pentru a aplica modificările pe care le-am făcut datelor și exportăm instanța bazei de date pentru a putea fi folosită în alte fișiere din proiectul nostru.
Flux de lucru general de solicitare/răspuns
Luați în considerare următoarea diagramă:
Acesta arată arhitectura generală aplicată într-o multitudine de aplicații backend construite cu NodeJs/Express. Înțelegerea fluxului de lucru general din spatele gestionării unei cereri nu vă va permite doar să construiți și să structurați aplicațiile NodeJ, ci vă va permite și să transferați aceste concepte în practic orice stivă tehnică la alegere. Vom explora diferitele straturi care interferează cu acest proces și le vom explica rolurile:
## Stratul de solicitare HTTP
Acesta este primul strat din aplicația noastră, imaginați-l ca pe o poartă care primește o gamă largă de solicitări diferite venite de la diferiți clienți, fiecare solicitare este apoi analizată și transmisă către partea dedicată a aplicației pentru ca aceasta să fie tratată.
-
Routere: aici ne referim la routere Express, dar acest concept poate fi găsit în multe cadre backend. Routerele sunt o modalitate de a aplica codul nostru distribuția logică din logica noastră de afaceri, ceea ce înseamnă că fiecare set de elemente care au caracteristici similare sunt tratate de aceeași intrare și pot fi separate de restul seturi. Acest lucru are avantajul de a face fiecare componentă a codului independentă de celelalte și mai ușor de întreținut și extins. Mai precis, și ca exemplu, toate cererile care îndeplinesc condițiile căii URL partajate „/posts” vor fi gestionate de același router. În funcție de metoda lor http (GET, POST, etc.), va fi folosit un controler diferit.
-
Controlere: un controler primește cereri filtrate de la routere, aplică procesări suplimentare și apelează metodele de service adecvate.
Stratul logică de afaceri
Acest strat este unic în funcție de cazurile de utilizare specifice ale aplicației și de logica de afaceri din spatele acesteia.
-
Servicii: Serviciile sunt un set de metode care conțin logica de bază a aplicației. De asemenea, interacționează cu baza de date prin utilizarea ORM-urilor/ODM-urilor.).
-
Servicii de la terți: multe aplicații moderne aleg să delege o parte din logica aplicației unor servicii dedicate accesibile printr-un API. Serviciile de acest fel pot fi servicii de gestionare a plăților, stocare de fișiere statice, notificări și altele.
-
ODM/ORM: ORM-urile și ODM-urile acționează ca intermediari între servicii și baza de date. Rolul lor este de a oferi o abstractizare la nivel înalt asupra unei baze de date care să permită unui dezvoltator să scrie cod în limbajul de programare ales în loc de limbaje de bază de date dedicate, cum ar fi SQL.
Stratul de persistență a datelor
- Baze de date: așa cum am menționat mai devreme, aproape toate aplicațiile au nevoie de o anumită formă de persistență a datelor. Această parte este gestionată de baze de date și, în funcție de natura datelor, logica afacerii și multe alte considerente, alegerea unei anumite baze de date în detrimentul alteia este considerată crucială pentru eficiența și scalabilitatea aplicației.
Exemplu: Adăugarea unei postări
Acum că înțelegem ideea generală din spatele arhitecturii, să o aplicăm exemplului nostru simplu. Vom implementa caracteristica de a adăuga o postare de tot în aplicația noastră. Să presupunem că orice postare are un id unic care ne va permite să o identificăm mai târziu în baza noastră de date, un titlu care este un șir și o ordine de tipul întreg. Urmând diagrama noastră, vom începe prin a implementa routerul. Adăugați următorul cod în fișierul index.js:
Acesta este fișierul nostru de router. Importăm expres și metoda „addPost” din controlerul nostru (o vom implementa pe aceasta în scurt timp), creăm o instanță de router expres și legăm metoda addPost la routerul nostru - adică pentru fiecare cerere care are calea rădăcină și http metoda „POST”, metoda „addPost” va fi apelată pentru a o gestiona.
Înainte de a implementa metoda noastră în controler, facem referință la noul router în fișierul nostru principal app.js și specificăm calea acestuia ca „/posts”: Toate rutele cu căile specificate vor fi redirecționate către acest router, astfel încât să poată fi gestionate prin diferite metode de control:
Importăm routerul și îl numim „postări”. app.use(“/posts”,..) înseamnă că toate cererile cu sub-calea „/posts”, indiferent de metoda lor http, vor fi direcționate către routerul specificat.
Alte modificări aduse app.js includ importarea fișierului de configurare a bazei de date pentru ca acesta să fie executat și utilizarea express.json() ca middleware pentru a ne permite să accesăm obiectul body request.
Acum că rutele noastre sunt setate, putem adăuga metoda „addPost” în fișierul controller.js:
„addPost” este o funcție middleware care ia ca parametri cererea, obiectele de răspuns și următoarea funcție. Când următoarea funcție este apelată, procesul va trece la următorul middleware din lanț sau va încheia cererea. În codul metodei, extragem titlul și ordinea din corpul cererii și le transmitem ca parametri funcției de serviciu „createPost”. Această funcție preia atributele postării, creează o nouă postare și o returnează. Odată ce noua postare este creată, o returnăm clientului împreună cu codul de stare 200, ceea ce înseamnă că solicitarea a avut succes. Este posibil să observați că codul nostru este introdus într-un bloc try/catch pentru a detecta orice eroare neașteptată și a o transmite următorului middleware. Este considerată cea mai bună practică să atașați la toate routerele un middleware de gestionare a erorilor care extrage eroarea și returnează un mesaj de eroare semnificativ către client.
Tot ce a mai rămas acum este să implementați funcția „createPost” în service.js:
După cum am menționat mai devreme când am explicat diferitele straturi ale arhitecturii, stratul de serviciu interacționează cu soluția de stocare a datelor prin utilizarea ORM/ODM. Cu toate acestea, în exemplul nostru, nu va trebui să folosim un ORM separat, deoarece Lowdb vine cu suport încorporat pentru Javascript. Toate detaliile despre sintaxa sa pot fi găsite în documentație.
Metoda „createPost” primește titlul și ordinea ca parametri și le folosește pentru a crea obiectul post. Pentru id-ul unic, folosim o bibliotecă dedicată numită „nanoid”, care generează o secvență unică de caractere. Adăugăm noua postare în tabloul de postări din baza de date și scriem aceste modificări; noua postare este apoi returnată de funcție.
Acum că „createPost” este gata, funcția de adăugare a postărilor este acum finalizată și în funcțiune. Îl testăm folosind Postman, un instrument popular pentru testarea API-urilor:
Selectăm „POST” ca metodă http pentru cerere împreună cu calea URL specificată „localhost:3000/posts”. Adăugăm titlul și ordinea în format json în secțiunea body și trimitem cererea. După cum se arată mai sus, primim starea 200 OK împreună cu postarea nou creată.
Concluzie
O mulțime de concepte și idei au fost explorate în acest proiect: am abordat cum să instalăm și să configuram mediul nostru de proiect, am învățat cum să configurați LowDB pentru persistența datelor locale, am explorat arhitectura generală a aplicațiilor backend NodeJS/Express și am văzut cum să aplicați-l într-un exemplu simplu. În cele din urmă, am testat aplicația noastră folosind Postman.
Intenția aici a fost de a expune o versiune simplificată a tot ceea ce este necesar pentru construirea de aplicații backend moderne. După cum am văzut mai devreme, NodeJs este un instrument puternic care ne permite să construim API-uri simple și complexe. Combinat cu ecosistemul său bogat de cadre, cum ar fi Express și o multitudine de instrumente și biblioteci pentru aproape orice caz de utilizare, este o soluție legitimă pentru dezvoltarea backend modernă - o soluție pe care vă recomandăm să o învățați și să o stăpânim.