Acest articol este o continuare a introducerii în stiva MEAN. Postul anterior a acoperit instalarea pachetului MEAN și, de asemenea, a prezentat ceea ce am ajuns în ceea ce privește structura directorului după instalare. Acum este timpul pentru o codificare reală!
Vom construi un cititor de flux RSS folosind stiva MEAN. Aplicația va permite utilizatorului să-și administreze lista de feed-uri prin adăugarea unui feed nou, ștergerea unui altul existent, modificarea unui deja existent și, bineînțeles, vizionarea unei liste cu toate fluxurile în care utilizatorul este interesat.
Utilizatorul trebuie să se autentifice pentru a avea acces la aplicație, astfel încât feed-urile unui utilizator să nu fie vizibile pentru alții și, cel mai important, pentru utilizatorii care nu sunt conectați. După cum am văzut în articolul precedent, stiva vine cu un mecanism complet de autentificare deja implementat, astfel încât îl putem folosi fără alte modificări.
Adresele URL ale feed-ului sunt stocate într-o bază de date Mongo de pe server, astfel încât acestea să fie disponibile chiar și după deconectare sau după închiderea browserului.
Ultimele feed-uri sunt afișate utilizatorului în pagina principală și vor afișa titlul articolului, un fragment și permit utilizatorului să facă clic pe titlu pentru a citi întregul mesaj.
Utilizatorul va avea, de asemenea, posibilitatea de a filtra fluxurile pe diverse criterii.
În această primă parte, vom discuta despre implementarea părții server a aplicației noastre (backend-ul). Vom implementa un API REST pentru a răspunde solicitărilor utilizatorului de vizualizare, crearea, ștergerea și modificarea feedurilor.
Din fericire pentru noi, stiva MEAN ne oferă un astfel de API pentru manipularea articolelor care pot fi create. Vom modifica acest API pentru a răspunde nevoii noastre de a gestiona adresele URL ale feedurilor. La urma urmei, acesta este motivul pentru care folosim codul boilerplate, pentru al modifica și adapta la nevoile aplicației noastre. Deci, să facem asta!
Să petrecem un minut și să ne gândim la ce rute ar trebui să răspundă aplicația noastră. Imaginea de mai jos arată ceea ce așteptăm să avem:
Acum, să deschidem dosarul app / rute / articles.js
. Dacă ne uităm la conținutul său, vedem că acesta este ceea ce dorim să avem, dar aplicat articolelor. Deci, trebuie să o modificăm puțin pentru a se potrivi nevoilor noastre. În primul rând, schimbați numele articles.js
la feeds.js
. Apoi modificați-o după cum se arată mai jos:
// app / routes / feeds.js "utilizarea strictă"; var feeds = necesită ("... / controlori / feed-uri"); var authorization = necesită ('./ middlewares / authorization'); // Ajutor pentru autorizarea feedurilor var hasAuthorization = function (req, res, next) if (req.feed.user.id! == req.user.id) return res.send (401, "Utilizatorul nu este autorizat") ; Următor →(); ; module.exports = funcție (app) app.get ('/ feeds', feeds.all); app.post ('/ feeds', authorization.requiresLogin, feeds.create); app.get ('/ feeds /: feedId', feeds.show); app.put ('/ feeds /: feedId', authorization.requiresLogin, areAutorizare, feeds.update); app.del ('/ feeds /: feedId', authorization.requiresLogin, areAutorizare, feeds.destroy); // Finalizați configurarea paragrafului feedId param app.param ('feedId', feeds.feed); ;
Pentru cei familiarizați cu framework-ul Express, acest lucru nu ar trebui să fie ceva nou, ci doar în caz, să mergem mai repede. Începem prin a cere feed-uri
controlerul (pe care îl vom vedea într-o clipă) și middleware-ul de autorizare (pe care o oferă stiva MEAN).
Apoi avem hasAuthorization ()
funcția, care compară id
a utilizatorului care dorește să manipuleze feedul cu id
din utilizatorul conectat și returnează o eroare dacă nu sunt aceleași. Următor →()
este un apel invers care permite ca următorul strat din stivele middleware să fie procesat.
În ultima parte, codul nostru exportează rutele așa cum este descris în tabelul de mai sus, implementând cerințele de securitate.
Crearea modelului aplicației utilizând mangustă
este o briza. Redenumiți app \ modele \ article.js
la app \ modele \ feed.js
și efectuați următoarele modificări:
"utilizarea strictă"; / ** * Dependente de module. * / var mongoose = necesită ('mongoose'), Schema = mongoose.Schema; / ** * Schema de alimente. * / var FeedsSchema = schema nouă (feedUrl: type: String, implicit: ", trim: true, user: type: Schema.ObjectId, ref: 'User'); (Cd); mongoose.model ("Fluxuri"); "" , FeedsSchema);
Definim structura bazei noastre de date aici, după cum urmează: vom avea un tabel de feeduri care conține a adresă url feed
câmpul de tip șir și o referință la utilizator
care va stoca id
din utilizatorul curent conectat. Observați că nu se ocupă de crearea unui id
pentru documentele noastre aici, deoarece acest lucru este luat de noi de sistemul MongoDB.
În cele din urmă, definim a sarcină()
funcția care filtrează documentele din baza de date în funcție de id
din utilizatorul curent conectat.
Controlorul este responsabil pentru implementarea funcțiilor solicitate de router, atunci când este cerut un anumit traseu. Toate funcțiile necesare pentru operațiile CRUD pe care le executăm sunt implementate în controler. Să aruncăm o privire la ele unul câte unul și să vedem detaliile implementării.
Ar trebui să observi un model prin acest punct. În primul rând, nu uitați să redenumiți app / controlere / articles.js
fișier la app / controlere / feeds.js
.
Pentru a crea un feed, implementăm crea()
funcţie:
/ ** * Creați un feed * / exports.create = funcția (req, res) var feed = noi Feeds (req.body); feed.user = req.user; feed.save (funcția (err) if (err) retur res.send ("utilizatori / înscriere", erori: err.errors, feed: feed else res.jsonp (feed); ); ;
În primul rând, creăm un a hrani
variabilă bazată pe Feed-uri
model. Apoi adăugăm la această variabilă referința la utilizatorul curent înregistrat pentru a fi stocat. În cele din urmă, numim modelul Salvați
pentru a stoca documentul în baza de date. La eroare, revenim la formularul de înscriere, deoarece cel mai probabil utilizatorul nu este conectat. Dacă documentul este creat cu succes, vom returna noul document apelantului.
/ ** * Actualizarea unui feed * / exports.update = funcția (req, res) var feed = req.feed; feed = _.extend (feed, req.body); feed.save (funcția (err) if (err) retur res.send ("utilizatori / înscriere", erori: err.errors, feed: feed else res.jsonp (feed); ); ;
Noi numim Lodash extinde
pentru a modifica proprietățile feedului cu cele care au venit de la utilizator. Apoi Salvați
metoda modelului stochează datele modificate în baza de date.
/ ** * Șterge o feed * / exports.destroy = funcție (req, res) var feed = req.feed; feed.remove (funcția (err) if (err) retur res.send ("utilizatori / înscriere", erori: err.errors, feed: feed else res.jsonp (feed); ); ;
Destul de simplu, nu-i așa? Modelul are a elimina
metodă care ne-a rezolvat foarte ușor problema.
Afișarea tuturor fluxurilor va fi sarcina părții client a aplicației noastre. Serverul va returna doar datele necesare:
/ ** * Lista fluxurilor * / exports.all = functie (req, res) Feeds.find () sort ('- creat') populate ('user', 'feedUrl' , feeds) if (err) res.render ('eroare', status: 500); altceva res.jsonp (feeds);); ;
Codul efectuează o căutare în baza de date care returnează utilizator
si adresă url feed
. Dacă găsi
eșuează, o eroare de server este returnată, altfel toate fluxurile găsite vor fi returnate.
O singură alimentare este afișată utilizând următoarele:
/ ** * Afișați un feed * / exports.show = funcție (req, res) res.jsonp (req.feed); ;
... care utilizează apoi o funcție de ajutor:
(err) returneaza urmatorul (err); daca (! feed) returneaza urmatoarea (eroare noua ('err' Imposibil de încărcat feed "+ id)); req.feed = feed; next ();); ;
... care încarcă un feed specific pe baza lui id
(care va fi ambalat în URL-ul).
Codul complet ar trebui să vă placă acest lucru:
// app / controllers / feeds.js "utilizarea strictă"; var mongoose = necesită ("mongoose"), Feeds = mongoose.model ("Feeds"), _ = necesită ("lodash"); (err) returneaza urmatorul (err); daca (! feed) returneaza urmatoarea (eroare noua ('err' Imposibil de încărcat feed "+ id)); req.feed = feed; next ();); ; / ** * Afișați un feed * / exports.show = funcție (req, res) res.jsonp (req.feed); ; / ** * Lista fluxurilor * / exports.all = functie (req, res) Feeds.find () sort ('- creat') populate ('user', 'feedUrl' , feeds) if (err) res.render ('eroare', status: 500); altceva res.jsonp (feeds);); ; / ** * Creați un feed * / exports.create = funcția (req, res) var feed = noi Feeds (req.body); feed.user = req.user; feed.save (funcția (err) if (err) retur res.send ("utilizatori / înscriere", erori: err.errors, feed: feed else res.jsonp (feed); ); ; / ** * Actualizarea unui feed * / exports.update = funcția (req, res) var feed = req.feed; feed = _.extend (feed, req.body); feed.save (funcția (err) if (err) retur res.send ("utilizatori / înscriere", erori: err.errors, feed: feed else res.jsonp (feed); ); ; / ** * Șterge o feed * / exports.destroy = funcție (req, res) var feed = req.feed; feed.remove (funcția (err) if (err) retur res.send ("utilizatori / înscriere", erori: err.errors, feed: feed else res.jsonp (feed); ); ;
Ei bine aproape. În acest moment nu avem partea clientului implementată pentru a demonstra că codul funcționează. Nu am prezentat testele unitare pentru acest cod, deoarece nu este atât de complicat și am vrut să-l las la tine ca pe un exercițiu.
Putem testa codul folosind aplicația Postman - REST Client disponibilă în Google Chrome.
Instalați Postman dacă nu îl aveți deja și configurați-l după cum urmează:
Celelalte părți ale codului sunt ușor de verificat, deci vă rugăm să vă distrați cu Postman și noua dvs. aplicație.
Utilizarea unui cod cadru sau a unui cod de bare poate, în unele situații, să fie utilă și să vă facă foarte productivi. După cum ați văzut în acest articol, implementarea API-ului REST necesar pentru aplicația noastră a fost redusă la efectuarea modificărilor minore ale codului de boilerplate. Desigur, pentru aplicații mai complexe, ar putea fi necesar să faci mai mult decât atât, dar, totuși, un punct de plecare poate fi util.
.