-
-
Save iksose/9401758 to your computer and use it in GitHub Desktop.
| Installing Node.js | |
| Go to http://nodejs.org, and click the Install button. | |
| Run the installer that you just downloaded. When the installer completes, a message indicates that Node was installed at /usr/local/bin/node and npm was installed at /usr/local/bin/npm. | |
| At this point node.js is ready to use. Let’s implement the webserver application from the nodejs.org home page. We will use it as a starting point for our project: a RESTful API to access data (retrieve, create, update, delete) in a wine cellar database. | |
| Create a folder named nodecellar anywhere on your file system. | |
| In the wincellar folder, create a file named server.js. | |
| Code server.js as follows: | |
| 1 | |
| 2 | |
| 3 | |
| 4 | |
| 5 | |
| 6 | |
| var http = require('http'); | |
| http.createServer(function (req, res) { | |
| res.writeHead(200, {'Content-Type': 'text/plain'}); | |
| res.end('Hello World\n'); | |
| }).listen(3000, '127.0.0.1'); | |
| console.log('Server running at http://127.0.0.1:3000/'); | |
| view rawserver.js hosted with ❤ by GitHub | |
| We are now ready to start the server and test the application: | |
| To start the server, open a shell, cd to your nodecellar directory, and start your server as follows: | |
| node server.js | |
| To test the application, open a browser and access http://localhost:3000. | |
| Installing Express | |
| Express is a lightweight node.js web application framework. It provides the basic HTTP infrastructure that makes it easy to create REST APIs. | |
| To install Express in the nodecellar application: | |
| In the nodecellar folder, create a file named package.json defined as follows: | |
| 1 | |
| 2 | |
| 3 | |
| 4 | |
| 5 | |
| 6 | |
| 7 | |
| 8 | |
| 9 | |
| { | |
| "name": "wine-cellar", | |
| "description": "Wine Cellar Application", | |
| "version": "0.0.1", | |
| "private": true, | |
| "dependencies": { | |
| "express": "3.x" | |
| } | |
| } | |
| view rawpackage.json hosted with ❤ by GitHub | |
| Open a shell, cd to the nodecellar directory, and execute the following command to install the express module. | |
| npm install | |
| A node_modules folder is created in the nodecellar folder, and the Express module is installed in a subfolder of node_modules. | |
| Now that Express is installed, we can stub a basic REST API for the nodecellar application: | |
| Open server.js and replace its content as follows: | |
| 1 | |
| 2 | |
| 3 | |
| 4 | |
| 5 | |
| 6 | |
| 7 | |
| 8 | |
| 9 | |
| 10 | |
| 11 | |
| 12 | |
| 13 | |
| var express = require('express'); | |
| var app = express(); | |
| app.get('/wines', function(req, res) { | |
| res.send([{name:'wine1'}, {name:'wine2'}]); | |
| }); | |
| app.get('/wines/:id', function(req, res) { | |
| res.send({id:req.params.id, name: "The Name", description: "description"}); | |
| }); | |
| app.listen(3000); | |
| console.log('Listening on port 3000...'); | |
| view rawserver.js hosted with ❤ by GitHub | |
| Stop (CTRL+C) and restart the server: | |
| node server | |
| To test the API, open a browser and access the following URLs: | |
| Get all the wines in the database: http://localhost:3000/wines | |
| Get wine with a specific id (for example: 1): http://localhost:3000/wines/1 | |
| Using Node.js Modules | |
| In a large application, things could easily get out of control if we keep adding code to a single JavaScript file (server.js). Let’s move the wine-related code in a wines module that we then declare as a dependency in server.js. | |
| In the nodecellar folder, create a subfolder called routes. | |
| In the routes folder create a file named wines.js and defined as follows: | |
| 1 | |
| 2 | |
| 3 | |
| 4 | |
| 5 | |
| 6 | |
| 7 | |
| exports.findAll = function(req, res) { | |
| res.send([{name:'wine1'}, {name:'wine2'}, {name:'wine3'}]); | |
| }; | |
| exports.findById = function(req, res) { | |
| res.send({id:req.params.id, name: "The Name", description: "description"}); | |
| }; | |
| view rawwines.js hosted with ❤ by GitHub | |
| Modify server.js as follows to delegate the routes implementation to the wines module: | |
| 1 | |
| 2 | |
| 3 | |
| 4 | |
| 5 | |
| 6 | |
| 7 | |
| 8 | |
| 9 | |
| 10 | |
| var express = require('express'), | |
| wines = require('./routes/wines'); | |
| var app = express(); | |
| app.get('/wines', wines.findAll); | |
| app.get('/wines/:id', wines.findById); | |
| app.listen(3000); | |
| console.log('Listening on port 3000...'); | |
| view rawserver.js hosted with ❤ by GitHub | |
| Restart the server and test the APIs: | |
| Get all the wines in the database: http://localhost:3000/wines | |
| Get wine with a specific id (for example: 1): http://localhost:3000/wines/1 | |
| The next step is to replace the placeholder data with actual data from a MongoDB database. | |
| Installing MongoDB | |
| To install MongoDB on your specific platform, refer to the MongoDB QuickStart. Here are some quick steps to install MongoDB on a Mac: | |
| Open a terminal window and type the following command to download the latest release: | |
| curl http://downloads.mongodb.org/osx/mongodb-osx-x86_64-2.2.0.tgz > ~/Downloads/mongo.tgz | |
| Note: You may need to adjust the version number. 2.2.0 is the latest production version at the time of this writing. | |
| Extract the files from the mongo.tgz archive: | |
| cd ~/Downloads | |
| tar -zxvf mongo.tgz | |
| Move the mongo folder to /usr/local (or another folder according to your personal preferences): | |
| sudo mv -n mongodb-osx-x86_64-2.2.0/ /usr/local/ | |
| (Optional) Create a symbolic link to make it easier to access: | |
| sudo ln -s /usr/local/mongodb-osx-x86_64-2.2.0 /usr/local/mongodb | |
| Create a folder for MongoDB’s data and set the appropriate permissions: | |
| sudo mkdir -p /data/db | |
| sudo chown `id -u` /data/db | |
| Start mongodb | |
| cd /usr/local/mongodb | |
| ./bin/mongod | |
| You can also open the MongoDB Interactive Shell in another terminal window to interact with your database using a command line interface. | |
| cd /usr/local/mongodb | |
| ./bin/mongo | |
| Refer to the MongoDB Interactive Shell documentation for more information. | |
| Installing the MongoDB Driver for Node.js | |
| There are different solutions offering different levels of abstraction to access MongoDB from Node.js (For example, Mongoose and Mongolia). A comparaison of these solutions is beyond the scope of this article. In this, guide we use the native Node.js driver. | |
| To install the the native Node.js driver, open a terminal window, cd to your nodecellar folder, and execute the following command: | |
| npm install mongodb | |
| Implementing the REST API | |
| The full REST API for the nodecellar application consists of the following methods: | |
| Method URL Action | |
| GET /wines Retrieve all wines | |
| GET /wines/5069b47aa892630aae000001 Retrieve the wine with the specified _id | |
| POST /wines Add a new wine | |
| PUT /wines/5069b47aa892630aae000001 Update wine with the specified _id | |
| DELETE /wines/5069b47aa892630aae000001 Delete the wine with the specified _id | |
| To implement all the routes required by the API, modify server.js as follows: | |
| 1 | |
| 2 | |
| 3 | |
| 4 | |
| 5 | |
| 6 | |
| 7 | |
| 8 | |
| 9 | |
| 10 | |
| 11 | |
| 12 | |
| 13 | |
| 14 | |
| 15 | |
| 16 | |
| 17 | |
| 18 | |
| var express = require('express'), | |
| wine = require('./routes/wines'); | |
| var app = express(); | |
| app.configure(function () { | |
| app.use(express.logger('dev')); /* 'default', 'short', 'tiny', 'dev' */ | |
| app.use(express.bodyParser()); | |
| }); | |
| app.get('/wines', wine.findAll); | |
| app.get('/wines/:id', wine.findById); | |
| app.post('/wines', wine.addWine); | |
| app.put('/wines/:id', wine.updateWine); | |
| app.delete('/wines/:id', wine.deleteWine); | |
| app.listen(3000); | |
| console.log('Listening on port 3000...'); | |
| view rawserver.js hosted with ❤ by GitHub | |
| To provide the data access logic for each route, modify wines.js as follows: | |
| 1 | |
| 2 | |
| 3 | |
| 4 | |
| 5 | |
| 6 | |
| 7 | |
| 8 | |
| 9 | |
| 10 | |
| 11 | |
| 12 | |
| 13 | |
| 14 | |
| 15 | |
| 16 | |
| 17 | |
| 18 | |
| 19 | |
| 20 | |
| 21 | |
| 22 | |
| 23 | |
| 24 | |
| 25 | |
| 26 | |
| 27 | |
| 28 | |
| 29 | |
| 30 | |
| 31 | |
| 32 | |
| 33 | |
| 34 | |
| 35 | |
| 36 | |
| 37 | |
| 38 | |
| 39 | |
| 40 | |
| 41 | |
| 42 | |
| 43 | |
| 44 | |
| 45 | |
| 46 | |
| 47 | |
| 48 | |
| 49 | |
| 50 | |
| 51 | |
| 52 | |
| 53 | |
| 54 | |
| 55 | |
| 56 | |
| 57 | |
| 58 | |
| 59 | |
| 60 | |
| 61 | |
| 62 | |
| 63 | |
| 64 | |
| 65 | |
| 66 | |
| 67 | |
| 68 | |
| 69 | |
| 70 | |
| 71 | |
| 72 | |
| 73 | |
| 74 | |
| 75 | |
| 76 | |
| 77 | |
| 78 | |
| 79 | |
| 80 | |
| 81 | |
| 82 | |
| 83 | |
| 84 | |
| 85 | |
| 86 | |
| 87 | |
| 88 | |
| 89 | |
| 90 | |
| 91 | |
| 92 | |
| 93 | |
| 94 | |
| 95 | |
| 96 | |
| 97 | |
| 98 | |
| 99 | |
| 100 | |
| 101 | |
| 102 | |
| 103 | |
| 104 | |
| 105 | |
| 106 | |
| 107 | |
| 108 | |
| 109 | |
| 110 | |
| 111 | |
| 112 | |
| 113 | |
| 114 | |
| 115 | |
| 116 | |
| 117 | |
| var mongo = require('mongodb'); | |
| var Server = mongo.Server, | |
| Db = mongo.Db, | |
| BSON = mongo.BSONPure; | |
| var server = new Server('localhost', 27017, {auto_reconnect: true}); | |
| db = new Db('winedb', server); | |
| db.open(function(err, db) { | |
| if(!err) { | |
| console.log("Connected to 'winedb' database"); | |
| db.collection('wines', {strict:true}, function(err, collection) { | |
| if (err) { | |
| console.log("The 'wines' collection doesn't exist. Creating it with sample data..."); | |
| populateDB(); | |
| } | |
| }); | |
| } | |
| }); | |
| exports.findById = function(req, res) { | |
| var id = req.params.id; | |
| console.log('Retrieving wine: ' + id); | |
| db.collection('wines', function(err, collection) { | |
| collection.findOne({'_id':new BSON.ObjectID(id)}, function(err, item) { | |
| res.send(item); | |
| }); | |
| }); | |
| }; | |
| exports.findAll = function(req, res) { | |
| db.collection('wines', function(err, collection) { | |
| collection.find().toArray(function(err, items) { | |
| res.send(items); | |
| }); | |
| }); | |
| }; | |
| exports.addWine = function(req, res) { | |
| var wine = req.body; | |
| console.log('Adding wine: ' + JSON.stringify(wine)); | |
| db.collection('wines', function(err, collection) { | |
| collection.insert(wine, {safe:true}, function(err, result) { | |
| if (err) { | |
| res.send({'error':'An error has occurred'}); | |
| } else { | |
| console.log('Success: ' + JSON.stringify(result[0])); | |
| res.send(result[0]); | |
| } | |
| }); | |
| }); | |
| } | |
| exports.updateWine = function(req, res) { | |
| var id = req.params.id; | |
| var wine = req.body; | |
| console.log('Updating wine: ' + id); | |
| console.log(JSON.stringify(wine)); | |
| db.collection('wines', function(err, collection) { | |
| collection.update({'_id':new BSON.ObjectID(id)}, wine, {safe:true}, function(err, result) { | |
| if (err) { | |
| console.log('Error updating wine: ' + err); | |
| res.send({'error':'An error has occurred'}); | |
| } else { | |
| console.log('' + result + ' document(s) updated'); | |
| res.send(wine); | |
| } | |
| }); | |
| }); | |
| } | |
| exports.deleteWine = function(req, res) { | |
| var id = req.params.id; | |
| console.log('Deleting wine: ' + id); | |
| db.collection('wines', function(err, collection) { | |
| collection.remove({'_id':new BSON.ObjectID(id)}, {safe:true}, function(err, result) { | |
| if (err) { | |
| res.send({'error':'An error has occurred - ' + err}); | |
| } else { | |
| console.log('' + result + ' document(s) deleted'); | |
| res.send(req.body); | |
| } | |
| }); | |
| }); | |
| } | |
| /*--------------------------------------------------------------------------------------------------------------------*/ | |
| // Populate database with sample data -- Only used once: the first time the application is started. | |
| // You'd typically not find this code in a real-life app, since the database would already exist. | |
| var populateDB = function() { | |
| var wines = [ | |
| { | |
| name: "CHATEAU DE SAINT COSME", | |
| year: "2009", | |
| grapes: "Grenache / Syrah", | |
| country: "France", | |
| region: "Southern Rhone", | |
| description: "The aromas of fruit and spice...", | |
| picture: "saint_cosme.jpg" | |
| }, | |
| { | |
| name: "LAN RIOJA CRIANZA", | |
| year: "2006", | |
| grapes: "Tempranillo", | |
| country: "Spain", | |
| region: "Rioja", | |
| description: "A resurgence of interest in boutique vineyards...", | |
| picture: "lan_rioja.jpg" | |
| }]; | |
| db.collection('wines', function(err, collection) { | |
| collection.insert(wines, {safe:true}, function(err, result) {}); | |
| }); | |
| }; | |
| view rawwines.js hosted with ❤ by GitHub | |
| Restart the server to test the API. | |
| Testing the API using cURL | |
| If you want to test your API before using it in a client application, you can invoke your REST services straight from a browser address bar. For example, you could try: | |
| http://localhost:3000/wines | |
| You will only be able to test your GET services that way. A more versatile solution to test RESTful services is to use cURL, a command line utility for transferring data with URL syntax. | |
| For example, using cURL, you can test the Wine Cellar API with the following commands: | |
| Get all wines: | |
| curl -i -X GET http://localhost:3000/wines | |
| Get wine with _id value of 5069b47aa892630aae000007 (use a value that exists in your database): | |
| curl -i -X GET http://localhost:3000/wines/5069b47aa892630aae000007 | |
| Delete wine with _id value of 5069b47aa892630aae000007: | |
| curl -i -X DELETE http://localhost:3000/wines/5069b47aa892630aae000007 | |
| Add a new wine: | |
| curl -i -X POST -H 'Content-Type: application/json' -d '{"name": "New Wine", "year": "2009"}' http://localhost:3000/wines | |
| Modify wine with _id value of 5069b47aa892630aae000007: | |
| curl -i -X PUT -H 'Content-Type: application/json' -d '{"name": "New Wine", "year": "2010"}' http://localhost:3000/wines/5069b47aa892630aae000007 |
whenever I do a operation that requires the id, I get,
TypeError: Cannot read property 'findOne' of undefined
In the meanwhile solved it following this instructions:
http://stackoverflow.com/questions/10929443/nodejs-mongodb-getting-data-from-collection-with-findone
@varmarakesh The mongodb calls must be in the routes/wines.js file.
@RAMIRIO @varmarakesh, I have the same problem. Typing wine = require('./routes/wines.js'); doesn't work.
Thanks for the great post, I'm up and running.
You can use POSTMAN to test the REST API:
https://chrome.google.com/webstore/detail/postman/fhbjgbiflinjbdggehcddcbncdddomop?hl=en
to fix the "Cannot read property 'findOne' of undefined":
http://stackoverflow.com/a/14551362
This is a good tutorial , Thanks
In Express 4, most middleware has been separated out from Express core. Thus, modules that are required by your app must be explicitly added. See http://expressjs.com/en/guide/migrating-4.html for details.
I made the following changes to server.js to get it to work for me in the Express 4.x context:
This...
var express = require('express'),
wine = require('./routes/wines');
var app = express();
app.configure(function () {
app.use(express.logger('dev')); /* 'default', 'short', 'tiny', 'dev' */
app.use(express.bodyParser());
});
becomes ...
var express = require('express');
var bodyParser = require('body-parser');
var morgan = require('morgan');
var wine = require('./routes/wines');
var app = express();
app.use(morgan('dev')); /* 'default','short','tiny','dev' */
app.use(bodyParser.urlencoded({extended:false}))
app.use(bodyParser.json());
note the change from "logger" in Express 3 to "morgan" in Express 4
I also added to my dependencies in Package.json:
"dependencies": {
"body-parser": "^1.15.2",
"express": "^4.14.0",
"mongodb": "^2.1.18",
"morgan": "^1.7.0"
}
... followed by "npm install"
Thanks to iksose for writing the original post, and to all the other commentators for contributing to the conversation.
Great gist/tut, this got me initiated into MEN's (Mongo, Express, Node) club :)
i have the same code
var express = require('express');
var bodyParser = require('body-parser');
var app = express();
app.use(bodyParser.urlencoded({extended:false}))
app.use(bodyParser.json());
but i get the message : app.use is not a function.
please, help me
I am contstantly getting this error.
module.js:440
throw err;
^
Error: Cannot find module './routes/wines'
at Function.Module._resolveFilename (module.js:438:15)
at Function.Module._load (module.js:386:25)
at Module.require (module.js:466:17)
at require (internal/module.js:20:19)
at Object. (/Users/amitasthana/nodeceller/server.js:4:12)
at Module._compile (module.js:541:32)
at Object.Module._extensions..js (module.js:550:10)
at Module.load (module.js:456:32)
at tryModuleLoad (module.js:415:12)
at Function.Module._load (module.js:407:3)
I have tried multiple things in comments, still not able to resolve the isssue. I used the format suggested by @wbj in the post. Any help would be highly appreciated. Am I missing something here. Thanks
how to start mongodb i have installed mongodb driver for nodejs
do i need to install mongodb too i have already installed mogodb driver for Nodejs ?
How do I write a routing for put? I'm having a hard time with the callbacks.
Its worked for me. Few changes you need to make in the code.
Modify the server.js as follow,
var express = require('express'),
wine = require('./routes/wines');
var app = express();
app.get('/wines', wine.findAll);
app.get('/wines/:id', wine.findById);
app.post('/wines', wine.addWine);
app.put('/wines/:id', wine.updateWine);
app.delete('/wines/:id', wine.deleteWine);
app.listen(3000);
console.log('Listening on port 3000...');
and wine.js as follow,
var mongo = require('mongodb');
var Server = mongo.Server,
Db = mongo.Db,
BSON = mongo.BSONPure;
var server = new Server('localhost', 27017, {auto_reconnect: true});
db = new Db('winedb', server);
db.open(function(err, db) {
if(!err) {
console.log("Connected to 'winedb' database");
db.collection('wines', {strict:true}, function(err, collection) {
if (err) {
console.log("The 'wines' collection doesn't exist. Creating it with sample data...");
populateDB();
}
});
}
});
exports.findById = function(req, res) {
var id = req.params.id;
console.log('Retrieving wine: ' + id);
db.collection('wines', function(err, collection) {
collection.findOne({'_id':new BSON.ObjectID(id)}, function(err, item) {
res.send(item);
});
});
};
exports.findAll = function(req, res) {
db.collection('wines', function(err, collection) {
collection.find().toArray(function(err, items) {
res.send(items);
});
});
};
exports.addWine = function(req, res) {
var wine = req.body;
console.log('Adding wine: ' + JSON.stringify(wine));
db.collection('wines', function(err, collection) {
collection.insert(wine, {safe:true}, function(err, result) {
if (err) {
res.send({'error':'An error has occurred'});
} else {
console.log('Success: ' + JSON.stringify(result[0]));
res.send(result[0]);
}
});
});
}
exports.updateWine = function(req, res) {
var id = req.params.id;
var wine = req.body;
console.log('Updating wine: ' + id);
console.log(JSON.stringify(wine));
db.collection('wines', function(err, collection) {
collection.update({'_id':new BSON.ObjectID(id)}, wine, {safe:true}, function(err, result) {
if (err) {
console.log('Error updating wine: ' + err);
res.send({'error':'An error has occurred'});
} else {
console.log('' + result + ' document(s) updated');
res.send(wine);
}
});
});
}
exports.deleteWine = function(req, res) {
var id = req.params.id;
console.log('Deleting wine: ' + id);
db.collection('wines', function(err, collection) {
collection.remove({'_id':new BSON.ObjectID(id)}, {safe:true}, function(err, result) {
if (err) {
res.send({'error':'An error has occurred - ' + err});
} else {
console.log('' + result + ' document(s) deleted');
res.send(req.body);
}
});
});
}
/--------------------------------------------------------------------------------------------------------------------/
// Populate database with sample data -- Only used once: the first time the application is started.
// You'd typically not find this code in a real-life app, since the database would already exist.
var populateDB = function() {
var wines = [
{
name: "CHATEAU DE SAINT COSME",
year: "2009",
grapes: "Grenache / Syrah",
country: "France",
region: "Southern Rhone",
description: "The aromas of fruit and spice...",
picture: "saint_cosme.jpg"
},
{
name: "LAN RIOJA CRIANZA",
year: "2006",
grapes: "Tempranillo",
country: "Spain",
region: "Rioja",
description: "A resurgence of interest in boutique vineyards...",
picture: "lan_rioja.jpg"
}];
db.collection('wines', function(err, collection) {
collection.insert(wines, {safe:true}, function(err, result) {});
});
};
FWIW, here's the original post.
I'm getting an error db.open is not a function at Object.<anonymous> (F:\Dev\Node projects\winecellar\routes\wines.js:10:4) at Module._compile (module.js:635:30) at Object.Module._extensions..js (module.js:646:10) at Module.load (module.js:554:32) at tryModuleLoad (module.js:497:12) at Function.Module._load (module.js:489:3) at Module.require (module.js:579:17) at require (internal/module.js:11:18) at Object.<anonymous> (F:\Dev\Node projects\winecellar\server.js:2:8) at Module._compile (module.js:635:30)
Please help tried all methods not able to find out the reason.
I'm getting an error
db.open is not a function at Object.<anonymous> (F:\Dev\Node projects\winecellar\routes\wines.js:10:4) at Module._compile (module.js:635:30) at Object.Module._extensions..js (module.js:646:10) at Module.load (module.js:554:32) at tryModuleLoad (module.js:497:12) at Function.Module._load (module.js:489:3) at Module.require (module.js:579:17) at require (internal/module.js:11:18) at Object.<anonymous> (F:\Dev\Node projects\winecellar\server.js:2:8) at Module._compile (module.js:635:30)Please help tried all methods not able to find out the reason.
I'm getting an error
db.open is not a function at Object.<anonymous> (F:\Dev\Node projects\winecellar\routes\wines.js:10:4) at Module._compile (module.js:635:30) at Object.Module._extensions..js (module.js:646:10) at Module.load (module.js:554:32) at tryModuleLoad (module.js:497:12) at Function.Module._load (module.js:489:3) at Module.require (module.js:579:17) at require (internal/module.js:11:18) at Object.<anonymous> (F:\Dev\Node projects\winecellar\server.js:2:8) at Module._compile (module.js:635:30)Please help tried all methods not able to find out the reason.
this is coming because of the mongodb version
change mongodb version in package.json to
"dependencies": {
"express": "^4.17.1",
"mongodb": "^2.2.33"
}
execute npm install
That's it
got this error
Error: .post() requires callback functions but got a [object Undefined]