In deze driedelige tutorial duiken we diep in het maken van een to-do list management-app in Node.js en Geddy. Dit is het laatste item in de serie, waar we ons blijven vervolgen Te doen
items naar MongoDB.
Als een snelle opfriscursus hebben we de vorige keer onze Te doen
bron en maakte een werkende takenlijsttoepassing, maar de gegevens bestonden alleen in het geheugen. In deze tutorial zullen we dat oplossen!
MongoDB is een NoSQL-database voor documentarchieven gemaakt door de mensen boven 10gen. Het is een geweldige database voor Node-apps omdat het zijn gegevens al in een JSON-achtige indeling opslaat en de query's zijn geschreven in JavaScript. We zullen het voor onze app gebruiken, dus laten we het instellen.
Ga naar http://www.mongodb.org/downloads en download de nieuwste versie voor uw besturingssysteem. Volg de instructies in het leesmij van daar. Zorg dat je kunt beginnen mongod
(en ga je gang en laat het draaien gedurende de duur van deze tutorial)
Het is vermeldenswaard dat u mongo moet uitvoeren wanneer u wilt dat uw app wordt uitgevoerd. De meeste mensen hebben dit ingesteld om met hun server op te starten met een upstart-script of iets dergelijks.
Gedaan? oké, laten we verder gaan.
Voor onze app gebruiken we een module die het mongodb-native database-stuurprogramma omwikkelt. Dit vereenvoudigt de code die we gaan produceren, dus laten we hem installeren. CD
in je app en voer deze opdracht uit:
npm install mongodb-wrapper
Als alles goed gaat, zou je een MongoDB-wrapper
map in uw node_modules
directory nu.
Mongo is een heel gemakkelijke database om mee te werken; u hoeft zich geen zorgen te maken over het instellen van tabellen, kolommen of databases. Gewoon door verbinding te maken met een database, creëer je er een! En door er iets aan toe te voegen, maak je er een. Dus laten we dit instellen voor onze app.
We hebben toegang tot onze DB-app nodig, dus laten we onze code instellen config / init.js
. Maak het open; het zou er zo uit moeten zien:
// Voeg niet-afgevangen-uitzondering-handler toe in prod-achtige omgevingen als (geddy.config.environment! = 'Development') process.addListener ('uncaughtException', function (err) geddy.log.error (JSON.stringify (err) ));); geddy.todos = []; geddy.model.adapter = ; geddy.model.adapter.Todo = require (process.cwd () + '/lib/model_adapters/todo').Todo;
Laten we bovenaan onze db-code toevoegen (en de geddy.todos-array verwijderen terwijl we bezig zijn):
var mongo = require ('mongodb-wrapper'); geddy.db = mongo.db ('localhost', 27017, 'todo'); geddy.db.collection ( 'todos'); // Voeg niet-afgevangen-uitzondering-handler toe in prod-achtige omgevingen als (geddy.config.environment! = 'Development') process.addListener ('uncaughtException', function (err) geddy.log.error (JSON.stringify (err) ));); geddy.model.adapter = ; geddy.model.adapter.Todo = require (process.cwd () + '/lib/model_adapters/todo').Todo;
Ten eerste hebben we de MongoDB-wrapper
module. Vervolgens stellen we onze database in en voegen we er een verzameling aan toe. Nauwelijks ingesteld.
Geddy maakt het niet zoveel uit welke back-end je gebruikt, zolang je maar een model-adapter hebt die ervoor is geschreven. Dit betekent dat de enige code die u in uw app moet wijzigen om uw te krijgen Te doen
s in een database zit in de model-adapter. Dat gezegd hebbende, zal dit een volledige herschrijving van de adapter zijn, dus als je je oude in-memory-app wilt behouden, wil je de code naar een andere map kopiëren.
Open je model-adapter (lib / model_adapters / todo.js
) en vind de opslaan
methode. Het zou er ongeveer zo uit moeten zien:
this.save = functie (todo, opts, callback) if (typeof callback! = 'function') callback = function () ; var todoErrors = null; for (var i in geddy.todos) // als het er al is, sla het op als (geddy.todos [i] .id == todo.id) geddy.todos [i] = todo; todoErrors = geddy.model.To.maken (todo) .errors; return callback (todoErrors, todo); todo.saved = true; geddy.todos.push (todo); return callback (null, todo);
Laat het er zo uitzien:
this.save = functie (todo, opts, callback) // soms hoeven we geen callback door te geven als (type van callback! = 'function') callback = function () ; // Mongo vindt het niet leuk als je er functies naar verzendt // dus laten we ervoor zorgen dat we alleen de eigenschappen gebruiken cleanTodo = id: todo.id, saved: todo.saved, title: todo.title, status : todo.status; // Controleer nogmaals of dit ding geldig is todo = geddy.model.Todo.create (cleanTodo); if (! todo.isValid ()) return callback (todo.errors, null); // Controleer om te zien of we dit al doen item geddy.db.todos.findOne (id: todo.id, functie (err, doc) if (err) return callback (err, null); // als we het te doen item al hebben, werk het dan bij met de nieuwe waarden als (doc) geddy.db.todos.update (id: todo.id, cleanTodo, function (err, docs) return callback (todo.errors, todo);); // als we het item nog niet hebben, sla dan een nieuw op todo.saved = true; geddy.db.todos.save (todo, function ( err, docs) return callback (err, docs);););
Laat je hier niet te zeer door afschrikken; we zijn eerst met de meest complexe begonnen. Vergeet niet dat onze opslaan
methode moet rekening houden met beide nieuw Te doen
s en oud bijwerken Te doen
s. Dus laten we deze code stap voor stap doorlopen.
We gebruiken dezelfde terugbelcode als eerder - als we geen terugverwijzing hebben ontvangen, gebruikt u gewoon een lege functie.
Dan zuiveren we onze Te doen
item. We moeten dit doen omdat onze Te doen
object heeft JavaScript-methoden erop (zoals opslaan
), en Mongo vindt het niet leuk als je objecten doorgeeft met methoden erop. Dus we maken gewoon een nieuw object met alleen de eigenschappen waar we om geven.
Vervolgens controleren we om te zien of het Te doen
is geldig. Als dit niet het geval is, noemen we de callback met de validatiefouten. Als dat zo is, gaan we verder.
In het geval dat we dit al hebben Te doen
item in de db, controleren we de db om te zien of a Te doen
bestaat. Dit is waar we het gebruik van beginnen te gebruiken MongoDB-wrapper
module. Het geeft ons een schone API om met onze db te werken. Hier gebruiken we de db.todos.findOne ()
methode om een enkel document te vinden dat aan onze vraag voldoet. Onze vraag is een eenvoudig js-object - we zijn op zoek naar een document waarvan ID kaart
is hetzelfde als onze Te doen
s ID kaart
. Als we er een vinden en er is geen fout, gebruiken we de db.todos.update ()
methode om het document bij te werken met de nieuwe gegevens. Als we er geen vinden, gebruiken we de db.todos.save ()
methode om een nieuw document op te slaan met de Te doen
gegevens van het item.
In alle gevallen roepen we een callback op als we klaar zijn, met eventuele fouten die we hebben en de documenten die de db aan ons heeft doorgegeven.
Bekijk de allemaal
methode, het zou er als volgt uit moeten zien:
this.all = function (callback) callback (nul, geddy.todos);
Laten we het er zo uit laten zien:
this.all = function (callback) var todos = []; geddy.db.todos.find (). sort (status: -1, title: 1). toArray (function (err, docs) // als er een fout is, ga vroeg terug als (err) return callback ( err, null); // doorloop de documenten en maak er modellen van voor (var i in docs) todos.push (geddy.model.Todo.create (docs [i])) return callback (null, todos););
Veel eenvoudiger dan de opslaan
methode, vind je niet? Wij gebruiken de db.todos.find ()
methode om alle items in de. te krijgen todos
verzameling. We gebruiken monogdb-wrapper
is api aan soort
de resultaten door staat
(in alfabetische volgorde) en door titel
(in oplopende alfabetische volgorde). Vervolgens sturen we dat naar een array, waardoor de query wordt gestart. Zodra we onze gegevens terug hebben, controleren we om te zien of er fouten zijn, als die er zijn, noemen we de callback met de fout. Als er geen fouten zijn, gaan we verder.
Vervolgens doorlopen we alle docs
(de documenten die mongo ons heeft gegeven), creëer nieuw Te doen
model exemplaren voor elk van hen, en duw ze naar een todos
matrix. Als we klaar zijn, noemen we de callback, passeren in de todos
.
Kijk eens naar de 'load'-methode, het zou er ongeveer zo uit moeten zien:
this.load = function (id, callback) for (var i in geddy.todos) if (geddy.todos [i]. id == id) return callback (null, geddy.todos [i]); callback (message: "To Do not found", null); ;
Laten we het er zo uit laten zien:
this.load = function (id, callback) var todo; // vind een todo in de db geddy.db.todos.findOne (id: id, functie (err, doc) // als er een fout is, ga vroeg terug als (err) return callback (err, null) ; // als er een document is, maak er dan een model van als (doc) todo = geddy.model.To.maken (doc); callback terugzet (null, todo);); ;
Deze is nog eenvoudiger. Wij gebruiken de db.todos.findOne ()
methode opnieuw. Deze keer is dat alles wat we moeten gebruiken. Als we een foutmelding hebben, noemen we het terugbellen ermee, zo niet, dan gaan we verder (zien we hier al een patroon?). Als we een document hebben, maken we een nieuw exemplaar van de Te doen
model en bel de callback ermee. Dat is het voor die.
Bekijk de verwijderen
methode nu, het zou er als volgt uit moeten zien:
this.remove = function (id, callback) if (typeof callback! = 'function') callback = function () ; voor (var i in geddy.todos) if (geddy.todos [i] .id == id) geddy.todos.splice (i, 1); return callback (nul); return callback (message: "To Do not found"); ;
Laten we het er zo uit laten zien:
this.remove = function (id, callback) if (typeof callback! = 'function') callback = function () ; geddy.db.todos.remove (id: id, functie (err, res) callback (err););
De verwijderingsmethode is zelfs korter dan vroeger. Wij gebruiken de db.todos.remove ()
methode om alle documenten te verwijderen die zijn ingeleverd ID kaart
en bel de callback met een fout (indien aanwezig).
Laten we onze app testen: CD
in de directory van uw project en start de server op met Geddy
. Maak een nieuw Te doen
. Probeer het te bewerken, laat een aantal validaties mislukken en probeer het te verwijderen. Het werkt allemaal!
Ik hoop dat je het leuk vond om meer te weten te komen over Node.js, MongoDB en vooral Geddy. Ik weet zeker dat je nu een miljoen ideeën hebt voor wat je ermee zou kunnen bouwen, en ik zou het leuk vinden om erover te horen. Zoals altijd, als je vragen hebt, laat hier een reactie achter of open een probleem met github.