Today we are going to create a demo to create API in nodejs with mongodb using express framework with better structure.
Tools required:
I asssume that you already have your environment set up (i.e Node.js and MongoDB is installed).
Kindly run npm -v
and mongo --version
as these will show you the version of NPM and MongoDB installed on your machine.
If you don’t have it installed, kindly go through the official site on how to install it in order for us to create a server in Node and Mongodb.
If you do have Node and MongoDB installed, let's begin the tutorial with the following basic steps.
Open your terminal and kindly follow the following steps
-
Create a Folder name node-mongo - mkdir node-mongo
-
Navigate to the root of your newly created folder - cd node-mongo
-
Create a package.json file - npm init
Package.json is a file that gives the necessary information to npm which allows it to identify the project as well as handle the project's dependencies.
npm init will prompt you to enter some information such as the app name, description, version, author, keyword and also ask if what you see is what you like.
Folder Structure:
DAO
--userDAO.js
Models
--User.js
node_modules
-----
------Packagaes installed by npm command is saved in node_modules.
------ `npm install Packagae1` is used to install any packagae
-------
Routes
--login.js
Services
--login.js
Utilities
--config.js
--environment.js
--mongooseConfig.js
--template.js
--util.js
package.json
server.js
In above folder we can see DAO folder, where we will perform entire mysql db query related task below that we have Models where we have models for defining the schema of the db tables, then node_modules which is created while installing node required packages. Next we have Routes & Services about which we will discuss later in this demo. Below that we have Utitlities folder where we have defined the configuration related stuff and common method which will be used throught the app and then package-lock.json which generated automatically by npm while installing packages and then package.json for storing the installed package related info and basic info of our application. At last we have server.js about which we will discuss in detail later
Lets have a look on our package.json file with needed package listed in it and basic detail of our app.
{
"name": "nodemongoapi",
"version": "1.0.0",
"description": "N/A",
"main": "server.js",
"author": "Suraj Roy",
"dependencies": {
"async": "^1.5.2",
"aws-sdk": "^2.16.0",
"body-parser": "^1.15.2",
"express": "^4.14.0",
"md5": "^2.2.1",
"mongoose": "^4.7.0",
"multer": "^1.3.0",
"mustache": "^2.3.0",
"nodemailer": "^2.6.4",
"request": "^2.85.0",
"scp2": "^0.5.0",
"xml2js": "^0.4.17"
}
}
In the above file we can see that the required packages are listed with its version.
In the next step, We have a file named server.js which performs perform the task i.e., accepts the input requests for parsing, routing, middleware set up and routing related things. So have a look on code inside it.
let app = require('express')(),
server = require('http').Server(app),
bodyParser = require('body-parser')
express = require('express'),
http = require('http'),
path = require('path');
let mongoose = require('./Utilities/mongooseConfig')();
let loginRoute = require('./Routes/login'),
util = require('./Utilities/util'),
config = require("./Utilities/config").config;
//input data parsing
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: false }));
app.use(function(err, req, res, next) {
return res.send({ "statusCode": util.statusCode.ONE, "statusMessage": util.statusMessage.SOMETHING_WENT_WRONG });
});
app.use('/auth', loginRoute); // app routing
// catch 404 and forward to error handler
app.use(function(req, res, next) {
next();
});
/*first API to check if server is running*/
app.get('/', function(req, res) {
res.send('hello, world!');
});
server.listen(config.NODE_SERVER_PORT.port,function(){ // server started here
console.log('app listening on port:'+config.NODE_SERVER_PORT.port);
});
Now lets move to routing part: app.use('/auth', loginRoute); is used to route the request to specific section. From here request will send to Routes folder inside login.js
router.post('/signup', (req, res) => {
loginService.signup(req.body, (data) => {
res.send(data);
});
});
It accepts the request so request with method signup hits here. And from here request sends to Services folder and hits the method with same name. Lets have a look the method inside Services folder.
let signup = (data, callback) => {
async.auto({
checkUserExistsinDB: (cb) => {
if (!data.fullName || !data.email || !data.password) {
cb(null, { "statusCode": util.statusCode.FOUR_ZERO_ONE, "statusMessage": util.statusMessage.PARAMS_MISSING })
return;
}
var criteria = {
email: data.email
}
userDAO.getUser(criteria, {}, {}, (err, dbData) => {
if (err){
cb(null, { "statusCode": util.statusCode.FOUR_ZERO_ONE, "statusMessage": util.statusMessage.SERVER_BUSY })
return;
}
if (dbData && dbData.length) {
if(dbData[0].isverified==true){
cb(null, { "statusCode": util.statusCode.FOUR_ZERO_THREE, "statusMessage": util.statusMessage.EMAIL_ALREADY_REGISTERED});
return;
}
var OTP = Math.floor(Math.random() * (99999999999 - 10000000 + 1)) + 1000;
var userData = {
"firstName": data.fullName.split(' ')[0],
"lastName": data.fullName.split(' ')[1],
"password": util.encryptData(data.password),
"email": data.email,
"phone": data.phone,
"status": 0, //0
"otp": OTP,
"isverified": 0, //0
"createdDate": new Date(),
"dateTimeOTP": Date.now()
}
var dataToSet = {
$set : userData
}
var criteria = {
email: data.email
};
userDAO.updateUser(criteria, dataToSet, {}, function(err, dbData) {
if (err) {
cb(null, { "statusCode": util.statusCode.ONE, "statusMessage": util.statusMessage.SERVER_BUSY });
} else {
cb(null, { "statusCode": util.statusCode.OK, "statusMessage": util.statusMessage.OTP_VERIFY, "result": dbData});
util.sendActivationMail({ "email": userData.email, "OTP": OTP,"baseUrl": config.NODE_SERVER_URL.url+":"+config.NODE_SERVER_PORT.port});
}
});
}
else {
cb(null);
}
});
},
createUserinDB: ['checkUserExistsinDB', (cb, functionData) => {
if (functionData.checkUserExistsinDB && functionData.checkUserExistsinDB.statusCode) {
cb(null, functionData.checkUserExistsinDB);
return;
}
var OTP = Math.floor(Math.random() * (9999999999 - 10000000 + 1)) + 1000;
var userData = {
"firstName": data.fullName.split(' ')[0],
"lastName": data.fullName.split(' ')[1],
"password": util.encryptData(data.password),
"email": data.email,
"phone": data.phone,
"status": 0, //0
"otp": OTP,
"isverified": 0, //0
"createdDate": new Date(),
"dateTimeOTP": Date.now()
}
console.log(userData,'test descc');
userDAO.createUser(userData, (err, dbData) => {
if (err) {
console.log(err);
cb(null, { "statusCode": util.statusCode.ONE, "statusMessage": util.statusMessage.SERVER_BUSY });
return;
}
cb(null, { "statusCode": util.statusCode.OK, "statusMessage": util.statusMessage.OTP_VERIFY, "result": dbData });
util.sendActivationMail({ "email": data.email, "OTP": OTP });
});
}]
}, (err, response) => {
callback(response.createUserinDB);
});
}
The above code performs the actual job. with async module. If any of the point is new then read from the offical site.
Thanks!