MEAN Stack - express, mongoose, mongoDB
Transkrypt
MEAN Stack - express, mongoose, mongoDB
MEAN Stack - express, mongoose, mongoDB Tworzenie serwisów Web 2.0 dr inż. Robert Perliński [email protected] Politechnika Częstochowska Instytut Informatyki Teoretycznej i Stosowanej MEAN Stack - express, mongoose, mongoDB 11 kwietnia 2016 1/43 Plan prezentacji 1 MEAN Stack 2 ExpressJS 3 mongoose Schematy w mongoose Opcje dla schematów Metody dostępu do bazy REST API 4 Źródła MEAN Stack - express, mongoose, mongoDB 2/43 MEAN Stack MEAN Stack - express, mongoose, mongoDB 3/43 MEAN Stack MEAN Stack - express, mongoose, mongoDB 4/43 Express http://expressjs.com/ Express to szybki, elastyczny (nie wymuszający konkretnych rozwiązań), minimalistyczny szablon aplikacji internetowych i mobilnych dla Node.js. $ npm install express --save MEAN Stack - express, mongoose, mongoDB 5/43 ExpressJS i warstwy pośrednie ExpressJS to komplenty framework. Działa z szablonami (jade, ejs, handlebars, hogan.js) i kompilatorami CSS (less, stylus, compass). Dzięki wartstwom pośredniczącym (oprogramowanie pośredniczące) obsługuje również: ciasteczka, sesje, buforowanie, CSRF, kompresję i wiele innych. Oprogramowanie pośredniczące: łańcuch/stos programów przetwarzających każde żądanie do serwera. Takich programów w stosie może być dowolna liczba, przetwarzanie odbywa się jeden po drugim. Niektóre z nich mogą zmieniać żądanie, tworzyć logi czy inne dane, przekazywać je do następnych (next()) programów w strumieniu. MEAN Stack - express, mongoose, mongoDB 6/43 Express-middlewares Warstwy pośredniczące dodajemy do ExpressJS używając app.use dla dowolnej metody albo app.VERB (np. app.get, app.delete, app.post, app.update, ...) MEAN Stack - express, mongoose, mongoDB 7/43 express Dodatkowe pakiety: npm install mongoose --save - biblioteka do pracy z MongoDB sudo npm install -g nodemon - automatycznie przeładowuje serwer po zmianach server.js var express = require('express') var app = express() app.get('/', function (req, res) { res.send('działa ale na razie statycznie') }) app.listen(3000) console.log('API działa na porcie 3000'); MEAN Stack - express, mongoose, mongoDB 8/43 mongoose http://mongoosejs.com/ Motywacja tworzenie walidacji dla MongoDB, rzutowania i szablonou logiki biznesowej jest dużym obciążeniem ... dletego używamy gotywych bibliotek, np. mongoose. Mongoose biblioteka dla Node.js, udostępnia mapowanie obiektowe (Object Data Mapping, ODM (ORM)) znany z Node.js interfejs, zamiana obiektów z bazy danych do JavaScript i odwrotnie. MEAN Stack - express, mongoose, mongoDB 9/43 mongoose http://mongoosejs.com/ Dostarcza gotowe rozwiązanie do modelowania danych aplikacji. Zawiera wbudowane: rzutowanie typów, walidację, budowanie zapytań, gotowe, praktyczne rozwiązania dla logiki biznesowej i wiele innych. MEAN Stack - express, mongoose, mongoDB 10/43 mongoose - sposób działania I Instalujemy mongoose w projekcie: npm install mongoose --save Dołączamy mongoose do projektu i łączymy się z bazą danych test (zostanie utworzona jeśłi takiej nie było): var mongoose = require('mongoose'); mongoose.connect('mongodb://localhost/test'); Sprawdzamy czy połączenie się udało: var db = mongoose.connection; db.on('error', console.error.bind(console, 'błąd połączenia...')); db.once('open', function() { // połączenie udane! }); W mongoose wszystko zaczyna się od schematu: var friendSchema = mongoose.Schema({ nazwa: String }); MEAN Stack - express, mongoose, mongoDB 11/43 mongoose - sposób działania II Mając schemat, na jego bazie tworzymy model var Friend = mongoose.model('Friend', friendSchema); Na bazie modelu tworzymy dokumenty (zawierają pola i typy jak w schemacie): var franek = new Friend({ nazwa: 'Franek' }); console.log(franek.nazwa); // 'Franek' Przyjaciele mogą się witać - zobaczmy, jak dodać funkcjonalność do naszych dokumentów: // metody należy dodać do schematu ZANIM utworzy się z niego model friendSchema.methods.sayHello = function () { var powitanie = this.nazwa ? "Cześć, mam na imię " + this.nazwa : "Witaj, nie wiem jak się nazywam ..."; console.log(powitanie); } MEAN Stack - express, mongoose, mongoDB 12/43 mongoose - sposób działania III Funkcja dodana do pola methods schematu i wykorzystana w modelu jest dostępna w każdym utworzonym dokumencie var jola = new Friend({ nazwa: 'Jolanta' }); jola.sayHello(); // "Cześć, mam na imię Jolanta" Zapis dokumentów w bazie odbywa się dzięki metodzie save(): // pierwszy argument odpowiada za błędy jola.save(function (err, jola) { if (err) return console.error(err); jola.sayHello(); }); MEAN Stack - express, mongoose, mongoDB 13/43 mongoose - sposób działania IV Odczyt dokumentów zapisanych w bazie, metoda find(): Friend.find(function (err, przyjaciele) { if (err) return console.error(err); for(var i=0; i<przyjaciele.length; i++) { console.log('%s', przyjaciele[i].nazwa); } }) Wyszukiwanie można prowadzić, np. po nazwie: find({ nazwa: /ˆJol/ } Friend.find({ nazwa: /^Jol/ }, function (err, przyjaciele) { if (err) return console.error(err); console.log("====================\n"); for(var i=0; i<przyjaciele.length; i++) { console.log('%s', przyjaciele[i].nazwa); } }); // lista przyjaciół nazywających sie Jol* MEAN Stack - express, mongoose, mongoDB 14/43 Schematy w mongoose Schemat odpowiada kolekcji w MongoDB, określa przechowywane dokumenty. var mongoose = require('mongoose'); var Schema = mongoose.Schema; var blogSchema = new Schema({ title: String, author: String, body: String, comments: [{ body: String, date: Date }], date: { type: Date, default: Date.now }, hidden: Boolean, meta: { votes: Number, favs: Number } }); Klucz określa pole dokumentu, wartość określa typ pola dokumentu. Pole tytul będzie typu String. Kluczom można przypisywać obiekty zagnieżdżone, które zawierają kolejne definicje klucz:typ, np. pole meta. MEAN Stack - express, mongoose, mongoDB 15/43 Typy danych schematów Dozwolone typy danych w mongoose: String, Number, Date, Buffer, Boolean, Mixed, ObjectId, Array. Schematy określają: strukturę dokumentu, metody instancyjne (działające na utworzonych dokumentach), statyczne metody modelu (działające na całym modelu), złożone indeksy, warstwy pośrednie związane z cyklem życia dokumentu. MEAN Stack - express, mongoose, mongoDB 16/43 Utworzenie modelu Mając utworzony schemat: var mongoose = require('mongoose'); var Schema = mongoose.Schema; var blogSchema = new Schema({ title: String, author: String, body: String, comments: [{ body: String, date: Date }], date: { type: Date, default: Date.now }, hidden: Boolean, meta: { votes: Number, favs: Number } }); tworzymy na jego bazie model: var Blog = mongoose.model('Blog', blogSchema); // wszystko gotowe, można pracować na bazie danych! MEAN Stack - express, mongoose, mongoDB 17/43 Metody instancyjne Dokumenty są instancjami modelu. Dokumenty zawierają wiele wbudowanych metod instancyjnych, np.: isDefault() - sprawdza czy pole dokumentu jest ustawione na wartość domyślną equals() - porównuje dwa dokumenty isInit() - sprawdza czy określone pole dokumentu zostało zainicjowane get() - zwraca wartość pola dokumentu set() - ustawia wartość pola lub wielu pól dokumentu ... - wiele innych wbudowanych metod Można definiować również własne metody instancyjne. MEAN Stack - express, mongoose, mongoDB 18/43 Własne metody instancyjne Definicja schematu i przypisanej do niego naszej własnej metody: var animalSchema = new Schema({ name: String, type: String }); animalSchema.methods.findSimilarTypes = function (callback) { return this.model('Animal').find({ type: this.type }, callback); } Wykorzystanie utworzonej metody na dokumencie: var Animal = mongoose.model('Animal', animalSchema); var burek = new Animal({ name: 'Burek', type: 'dog' }); var tarzan = new Animal({ name: 'Tarzan', type: 'dog' }); var bunia = new Animal({ name: 'Bunia', type: 'cat' }); burek.save(); tarzan.save(); bunia.save(); burek.findSimilarTypes(function (err, animals) { for(var i=0; i<animals.length; i++) { console.log(animals[i].name); // Burek } // Tarzan }); MEAN Stack - express, mongoose, mongoDB 19/43 Statyczne metody modelu Przypisanie metody do schematu jako statycznej: // metoda przypisywana do schematu jako statics animalSchema.statics.findByName = function (name, callback) { return this.find({ name: new RegExp(name, 'i') }, callback); } Wykorzystanie utworzonej metody na całym modelu: var Animal = mongoose.model('Animal', animalSchema); Animal.findByName('Bu', function (err, animals) { console.log("Zwierzęta na Bu"); for(var i=0; i<animals.length; i++) { console.log(JSON.stringify(animals[i])); } }); // Zwierzęta na Bu // {"name":"Burek","type":"dog",...} // {"name":"Bunia","type":"cat",...} MEAN Stack - express, mongoose, mongoDB 20/43 Warstwy pośrednie związane z cyklem życia dokumentu I Warstwy pośrednie związane z cyklem życia dokumentu: funkcje, którym przekazuje się sterowanie podczas wykonywania funkcji asynchronicznych, tworzy się je na poziomie schematu, nadają się do tworzenia pluginów, są ich dwa rodzaje: funkcje dla dokumentów, funkcje dla zapytań Dla dokumentów są dostępne funkcje: init validate save remove Dla zapytań są dostępne funkcje: count findOne findOneAndUpdate find findOneAndRemove update W obydwu przypadkach dostępne są wywołania przed (pre) i po (post) funkcji dokumentów czy zapytań. MEAN Stack - express, mongoose, mongoDB 21/43 Warstwy pośrednie związane z cyklem życia dokumentu II Przykłady funkcji uruchamianych przed i po wybranej funkcji var schema = new Schema(..); schema.pre('save', function(next) { // działanie przed zapisaniem obiektu w bazie... next(); }); Działanie przed i po wykonaniu metody find() schema.pre('find', function() { console.log(this instanceof mongoose.Query); // true this.start = Date.now(); }) schema.post('find', function(result) { console.log(this instanceof mongoose.Query); // true // wyświetlenie zwróconych dokuemtnów console.log('find() zwróciło ' + JSON.stringify(result)); // wyświetlenie ile czasu zajęło zapytanie console.log('find() trwało ' + (Date.now() - this.start) + ' ms'); }); MEAN Stack - express, mongoose, mongoDB 22/43 Opcje dla schematów Schematy mają kilka opcji, które można przekazać do konstruktora albo ustawić bezpośrednio: new Schema({..}, opcje); // albo var schema = new Schema({..}); schema.set(opcja, wartosc); Dozwolone opcje w schematach mongoose: autoIndex minimize toObject capped read typeKey collection safe validateBeforeSave emitIndexErrors shardKey versionKey id strict skipVersioning toJSON timestamps id MEAN Stack - express, mongoose, mongoDB 23/43 Opcje schematów - capped, collection capped - pozwala tworzyć ”nakryte” kolekcje ( mające stały rozmiar, jeśli braknie miejsca nowe elementy zastępują stare); należy podać maksymalny rozmiar kolekcji w bajtach new Schema({..}, { capped: 1024 }); // albo // max - maksymalna liczba dokumentów w kolekcji new Schema({..}, { capped: { size: 1024, max: 1000, autoIndexId: true } }); collection - pozwala określić nazwę tworzonej przez mongoose kolekcji. Nazwa kolekcji nadana w modelu nie ma znaczenia! var dataSchema = new Schema({..}, { collection: 'data' }); // przykładowo: var animalSchema = new Schema( { name: String, type: String }, { collection: 'zwierzaki'}); MEAN Stack - express, mongoose, mongoDB 24/43 Opcje schematów - strict strict - włączenie tej opcji (działanie domyślne) zapewnia, że pola z dokumentu nie występujące w schemacie nie zapiszą się w bazie var animSchema = new Schema({ name: String, type: String }); var Anim = mongoose.model('Anim', animSchema); var burek = new Anim({ name: 'Burek', type: 'dog', genus: 'ssak' }); burek.save(); // pole genus NIE zostało zapisane w bazie // wyłączenie opcji strict var animSchema = new Schema({ name: String, type: String }, { strict: false }); var Anim = mongoose.model('Anim', animSchema); var burek = new Anim({ name: 'Burek', type: 'dog', genus: 'ssak' }); burek.save(); // pole genus zostało zapisane w bazie opcję strict można również ustawić na poziomie modelu podając jako drugi argument wartość bool var Anim = mongoose.model('Anim', animSchema); var burek = new Anim({ name: 'Burek', type: 'dog', genus: 'ssak' }, true); var burek = new Anim({ name: 'Burek', type: 'dog', genus: 'ssak' }, false); MEAN Stack - express, mongoose, mongoDB 25/43 Opcje schematów - versionKey versionKey - odpowiada za pole automatycznie dodawane do dokumentu określające jego wersję; domyślnie jest to v { "name" : "Burek", "type" : "dog", "_id" : ObjectId("5708432cd4fc2be734d13935"), "__v" : 0 } opcja pozwala określić nową nazwę dla pola do wersjonowania var animalSchema = new Schema({ name: String, type: String }, { versionKey: 'wersja' } ); { "name" : "Burek", "type" : "dog", "_id" : ObjectId("5708478671422bcc363df3dd"), "wersja" : 0 } jak również całkowicie wyłączyć wersjonowanie var animalSchema = new Schema({ name: String, type: String }, { versionKey: false } ); { "name" : "Burek", "type" : "dog", "_id" : ObjectId("570848e085e92fac375108d2") } MEAN Stack - express, mongoose, mongoDB 26/43 Opcje schematów - timestamps timestamps - włączenie opcji (domyślne wyłączona) tworzy w schemacie automatycznie pola createdAt i updatedAt typu Data var animalSchema = new Schema({ name: String, type: String }, { timestamps: true } ); { "updatedAt" : ISODate("2016-04-08T23:47:56.601Z"), "createdAt" : ISODate("2016-04-08T23:47:56.601Z"), "name" : "Burek", "type" : "dog", "_id" : ObjectId("5708432cd4fc2be734d13935"), "__v" : 0 } domyślne nazwy pól można zastąpić innymi var animalSchema = new Schema( { name: String, type: String } { timestamps: {createdAt: 'utworzony', updatedAt: 'zakutalizowany'} } ); { "zakutalizowany" : ISODate("2016-04-08T23:54:35.028Z"), "utworzony" : ISODate("2016-04-08T23:54:35.028Z"), "name" : "Puszek", "type" : "cat", "_id" : ObjectId("570844bb80897792353a2fef"), "__v" : 0 } MEAN Stack - express, mongoose, mongoDB 27/43 mongoose - utworzenie modelu i schematu Dostęp do bazy danych wymaga utworzenia schematu i następnie modelu. Schemat osobaSchema i model Osoba będą wykorzystane w kolejnych przykładach. Nazwa utworzonej kolekcji to osoby. var osobaSchema = new mongoose.Schema({ imie: String, nazwisko: String, wiek: Number }, { collection: "osoby" }); var Osoba = mongoose.model('nazwaBezZnaczenia', osobaSchema); MEAN Stack - express, mongoose, mongoDB 28/43 mongoose - zapis do bazy, new i save Mając model Osoba tworzymy nowy obiekt na bazie modelu (new) i zapisujemy go (save): var Osoba = mongoose.model('nazwaBezZnaczenia', osobaSchema); var rob = new Osoba({imie:'Robert', nazwisko:'Lewandowski', wiek:27}); // zapis do bazy rob.save(function (err) { if (err) { console.log(err); } else { console.log('zapisano'); } }); MEAN Stack - express, mongoose, mongoDB 29/43 mongoose - zapis do bazy, create create - skrót do utworzenia nowego dokumentu, który jest automatycznie zapisywany w bazie jeśli jest prawidłowy; można przekazywać jeden dokument, listę dokumentów oddzielonych przecinkiem albo całą tablicę: Osoba.create({ imie: 'Jan', nazwisko: "Nowak" }, function (err, os) { if (err) return handleError(err); console.log(JSON.stringify(os)); }) Osoba.create( { imie: 'Franek', nazwisko: "Marchewka" }, { imie: 'Zofia', nazwisko: "Głąb" }, function (err, os) { if (err) return handleError(err); console.log(JSON.stringify(os)); // wyświetli tylko ostatni zapisany dokument }) Osoba.create( [ { imie: 'Jola' }, { imie: 'Józefa' }, { imie:"Adam"} ], function (err, os) { if (err) return handleError(err); console.log(JSON.stringify(os)); // wyświetli wszystkie zapisane dokumenty }) MEAN Stack - express, mongoose, mongoDB 30/43 mongoose - zapytania dostępna jest bogata składnia zapytań z MongoDB: find(), findById(), findOne() i where() Osoba.find(function (err, osoby) { // wszystkie osoby z kolekcji if (err) return next(err); console.log(JSON.stringify(osoby)); }); Osoba.find( {imie:new RegExp('an', 'i')} ,function (err, osoby) { if (err) return next(err); console.log(JSON.stringify(osoby)); // osoby z imieniem zaw. 'an' }); Osoba.findOne( {nazwisko:new RegExp('k','i'), wiek: {$gte: 25} } ,function (err, osoby) { if (err) return next(err); console.log(JSON.stringify(osoby)); // tylko pierwsza os. spełniająca warunki }); Osoba.findById( "570929216e8a2a5f23863676" ,function (err, osoba) { console.log(JSON.stringify(osoba)); // osoba z podanym id }); MEAN Stack - express, mongoose, mongoDB 31/43 mongoose - usuwanie dokumentów remove(warunki, [funZw]) - usuwa wszystkie dokumenty spełniające podane warunki findByIdAndRemove(id, [opcje], [funZw]) - usuwa dokument o podanym id, zwraca usuwany dokument przez funZw findOneAndRemove(warunki, [opcje], [funZw]) - usuwa pierwszy z dokumentów spełniających podane warunki, zwraca usuwany dokument przez funZw Osoba.remove( { imie : 'Józefa' } ,function (err, osoba) { // {"ok":1,"n":1} - liczba usuniętych dokumentów console.log(JSON.stringify(osoba)); }); Osoba.findByIdAndRemove( "57092733d5073d6d22307d4c", function (err, osoba) { console.log(JSON.stringify(osoba)); // wyświetla usuwany dokument }); Osoba.findOneAndRemove( {nazwisko:{$exists:false} }, function (err, osoba) { console.log(JSON.stringify(osoba)); // wyświetla usunięty dokument }); MEAN Stack - express, mongoose, mongoDB 32/43 mongoose - aktualizacja dokumentów Są różne sposoby na aktualizację danych. Najprościej zmienić pobrany dokument i ponownie go zapisać: Osoba.findById( "57092733d5073d6d22307d4a" ,function (err, osoba) { osoba.nazwisko = 'Dąbek'; osoba.save(function (err) { if (err) return handleError(err); console.log(JSON.stringify(osoba)); }); }); update(warunki, aktualizacja, [opcje], [funZw]) - aktualizuje wiele dokumentów, wszystkie, które spełniają warunki, nie zwraca zmienionych dokumentów Osoba.update( { _id:"57092733d5073d6d22307d4a" }, { $set: {wiek: 18} }, function (err, osoba) { // {"ok":1,"n":1} - liczba zaktualizowanych dokumentów console.log(JSON.stringify(osoba)); }); MEAN Stack - express, mongoose, mongoDB 33/43 mongoose - aktualizacja dokumentów findByIdAndUpdate(id, [aktualizacja], [opcje], [funZw]) aktualizuje dokument o podanym id, zwraca usuwany dokument przez funZw findOneAndUpdate([warunki], [aktualizacja], [opcje], [funZw]) aktualizuje pierwszy z dokumentów spełniających podane warunki, zwraca usuwany dokument przez funZw Osoba.findByIdAndUpdate( "57092733d5073d6d22307d4a", { $set: { wiek: 28 } }, function (err, osoba) { console.log(JSON.stringify(osoba)); // wyświetla aktualizowany dokument }); Osoba.findOneAndUpdate( { nazwisko: { $exists:false } }, { $set: { nazwisko:"Rał" }}, function (err, osoba) { if (err) return handleError(err); console.log(JSON.stringify(osoba)); // wyświetla aktualizowany dokument }); MEAN Stack - express, mongoose, mongoDB 34/43 mongoose - opis API Klasyczne API RESTful, zawiera cztery podstawowwe operacje CRUD: Resource (URI) /zadania /zadania/:id POST (create) nowe zad. błąd MEAN Stack - express, mongoose, mongoDB GET (read) lista zad. zad. o :id PUT (update) błąd aktualizacja :id DELETE (destroy) błąd usuń 1 zad. o ID 35/43 Proste API RESTful - całość aplikacji api.js var var var var express = require('express'); mongoose = require('mongoose'); bodyParser = require('body-parser'); app = express(); // parse application/x-www-form-urlencoded app.use(bodyParser.urlencoded({ extended: false })) app.use(bodyParser.json()); // parse application/json // ... schemat i model // ... obsługa API app.get('/', function(req, res) { res.end("Witam Was serdecznie na mojej stronie :)"); }) app.listen(5000); MEAN Stack - express, mongoose, mongoDB 36/43 Proste API RESTful - schemat i model Schemat zawiera 5 pól, 2 zawierają wartości domyślne. Model tworzy kolekcję o nazwie tasks. Obiekt Zadanie pozwala na dostęp do bazy danych. api.js var zadSchema = new mongoose.Schema({ nazwa: String, zakonczone: Boolean, notatka: String, rodzaj: { type: String, default: "praca" }, utworzone: { type: Date, default: Date.now } }); var Zadanie = mongoose.model('task', zadSchema); MEAN Stack - express, mongoose, mongoDB 37/43 Proste API RESTful - lista dokumentów wykorzystanie metody GET dla wyświetlenia danych wykorzystanie metody find() dla odczytu wszystkich danych dane zwrócone w postaci JSONa api.js /* GET /zadania - lista zadań */ app.get('/zadania', function(req, res, next) { Zadanie.find(function (err, zadania) { if (err) return next(err); res.json(zadania); }); }); MEAN Stack - express, mongoose, mongoDB 38/43 Proste API RESTful - dodawanie dokumentu wykorzystanie metody POST dla utworzenia danych wykorzystanie metody create() - tworzy i od razu zapisuje dane dane z zapytania pobrane dzięki warstwie body-parser dane zwrócone w postaci JSONa api.js /* POST /zadania - dodawanie zadania */ app.post('/zadania', function(req, res, next) { Zadanie.create(req.body, function (err, zad) { if (err) return next(err); res.json(zad); }); }); MEAN Stack - express, mongoose, mongoDB 39/43 Proste API RESTful - tylko wybrany dokument wykorzystanie metody GET dla wyświetlenia danych wykorzystanie metody findById() dla odczytu jednego dokumentu parametr id określa zwracany dokument dane zwrócone w postaci JSONa api.js /* GET /zadania/id - wyświetlenie wybranego zadania */ app.get('/zadania/:id', function(req, res, next) { Zadanie.findById(req.params.id, function (err, zad) { if (err) return next(err); res.json(zad); }); }); MEAN Stack - express, mongoose, mongoDB 40/43 Proste API RESTful - aktualizacja dokumentu wykorzystanie metody PUT dla aktualizacji danych wykorzystanie metody findByIdAndUpdate() do aktualizacji wybranego dokumentu parametr id określa wybrany (i zwracany) dokument parametr req.body odpowiada za opcje, np. jakie pola dokumentu mają być zwrócone: { "select": { "nazwa":true } } dane zwrócone w postaci JSONa api.js /* PUT /zadania/:id - aktualizacja zadania */ app.put('/zadania/:id', function(req, res, next) { Zadanie.findByIdAndUpdate(req.params.id, req.body, function (err, zad) { if (err) return next(err); res.json(zad); }); }); MEAN Stack - express, mongoose, mongoDB 41/43 Proste API RESTful - usuwanie dokumentu wykorzystanie metody DELETE dla usuwania danych wykorzystanie metody findByIdAndRemove() do usunięcia wybranego dokumentu parametr id określa usuwany (i zwracany) dokument parametr req.body odpowiada za opcje, np. jakie pola dokumentu mają być zwrócone: { "select": { "nazwa":true } } dane zwrócone w postaci JSONa api.js /* DELETE /zadania/:id - usuwanie zadania */ app.delete('/zadania/:id', function(req, res, next) { Zadanie.findByIdAndRemove(req.params.id, req.body, function (err, zad) { if (err) return next(err); res.json(zad); }); }); MEAN Stack - express, mongoose, mongoDB 42/43 Źródła https://nodejs.org/en/ https://en.wikipedia.org/wiki/Node.js http://expressjs.com/ https://en.wikipedia.org/wiki/Express.js http://www.tutorialspoint.com/nodejs/index.htm https://www.npmjs.com/ https://github.com/libuv/libuv https://en.wikipedia.org/wiki/Callback_(computer_programming) http://jade-lang.com/ http://mongoosejs.com/ http://aaronheckmann.tumblr.com/post/48943525537/ mongoose-v3-part-1-versioning MEAN Stack - express, mongoose, mongoDB 43/43