Async/await is the lastest and smarter approach to write asynchronous code. It Increases the performance and responsiveness of the application, particularly when you have long-running operations that do not require to block the execution. In this case, you can perform other work while waiting for the result from the long-running task. The big difference is that asynchronous code written with Async/Await looks and behaves like synchronous code. With Async/Await less code is needed to write and it's more readable than callback and promise approach.
Before Async/Await we all mainly used callback and promises
Example of callback
setTimeout(() => {
console.log('This runs after 1000 milliseconds.');
}, 1000);
Problem with Callbacks- Callback hell
functionOne(()=>{
functionTwo(()=>{
functionThree(()=>{
functionFour(()=>{
functionFive(()=>{
--- perform some operations here
------------------------------
})
})
})
})
})
The above one is mainly a situation where callbacks are nested within one other callback for multiple times, And making it difficult to understand and maintain the code.
Example of Promise
Let's have a look a basic promise:
// Return new promise
const promiseFun = new Promise(function(resolve, reject) {
request.get({url: 'url-for-request',headers: {'User-Agent': 'request'}}, function(err, resp, body) {
if (err) {
reject(err);
} else {
resolve(JSON.parse(body));
}
})
})
promiseFun.then(function(result) {
console.log(result)
}, function(err) {
console.log(err);
})
In the above code, promiseFunc returns a Promise that represents the process of that function. The resolve function signals the Promise instance that it has finished.
Afterwards, we can call .then() and .catch() on that promise function:
then?—?Runs a callback you pass to it when the promise has finished.
catch?—?Runs a callback you pass to it when something went wrong.
Let's Get Started Creating API with Async/Await
Here we will understand to create Basic APIs registration and login with Async/Await .
have a look on the folder structure:
package.json
Have a look inside package.json file.
{
"name": "server",
"version": "1.0.0",
"description": "",
"main": "server.js",
"scripts": {
"test": "echo "Error: no test specified" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"body-parser": "^1.19.0",
"cors": "^2.8.5",
"express": "^4.17.1",
"http": "0.0.0",
"md5": "^2.2.1",
"mongoose": "^5.6.1"
}
}
server.js
/**
* Module dependencies.
*/
const express = require('express');
const app = express();
const path = require('path');
const server = require('http').Server(app);
const bodyParser = require('body-parser');
const cors = require('cors');
var User = require('./Models/User')
const mongoose = require('./Utilities/mongooseConfig')();
const authRoute = require('./Routes/auth');
const config = require("./Utilities/config").config;
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({
extended: false
}));
app.use(cors());
app.use((err, req, res, next) => {
return res.send({
"statusCode": 401,
"statusMessage": "Something went wrong"
});
});
app.use('/auth', authRoute);
// catch 404 and forward to error handler
app.use((req, res, next) => {
next();
});
/**
* Start Express server.
*/
server.listen(config.NODE_SERVER_PORT.port, () => {
console.log('app listening on port:' + config.NODE_SERVER_PORT.port);
});
In the code, we can see the npm packages needed, middleware function, routing and server started at the bottom of the file.
auth.js
const config = require("../Utilities/config").config;
const UserDAO = require('../DAO/userDAO');
const MD5 = require('md5');
/* API to register new user */
let register = async (req, res) => {
if (!req.body.email || !req.body.password) {
res.status(401).json({message:'Parameters are missing'})
} else {
try {
let criteria = {
email: req.body.email
}
const checkEmail = await UserDAO.getUsers(criteria);
if (checkEmail && checkEmail.length==1) {
res.status(401).json({message:'email already registered'})
} else {
let userData = {
firstName: req.body.firstName ? req.body.firstName : "",
lastName: req.body.lastName ? req.body.lastName : "",
email: req.body.email,
phone: req.body.phone,
password: MD5(MD5(req.body.password)),
status: true
};
const addUser = await UserDAO.createUser(userData);
// console
if (addUser) {
res.status(200).json({message:'User registered successfully!'})
} else {
res.status(403).json({message:"Something went wrong"});
}
}
} catch (error) {
res.status(404).json({message:"Something went wrong",error:error});
}
}
};
/* API to login user */
let login = async (req, res) => {
if (!req.body.email || !req.body.password) {
res.status(401).json({message:'Parameters are missing'});
} else {
try {
let criteria = {
email: req.body.email,
status: true
};
const checkEmail = await UserDAO.getUsers(criteria);
if (checkEmail) {
let criteria = {
email: req.body.email,
password: MD5(MD5(req.body.password))
};
const checkPassword = await UserDAO.getUsers(criteria);
if (checkPassword && checkPassword.length==1) {
res.status(200).json({message:'Logged in successfully!',result:checkPassword});
} else {
res.status(401).json({message:'Incorrect password'});
}
} else {
res.status(401).json({message:'Email not exist!'});
}
} catch (error) {
res.status(401).json({message:'Something went wrong',error:error});
}
}
};
module.exports = {
register: register,
login: login
}
In the above code, there is the main logic of the APIs. APIs are created with Async/Await.
userDAO.js
"use strict";
var Models = require("../Models/User");
const getUsers = criteria =>
new Promise((resolve, reject) => {
Models.find(criteria)
.then(client => resolve(client))
.catch(err => reject(err));
});
const createUser = objToSave =>
new Promise((resolve, reject) => {
new Models(objToSave)
.save()
.then(client => resolve(client))
.catch(err => {reject(err);
console.log(err);
});
});
const updateUser = (criteria, dataToSet, options) =>
new Promise((resolve, reject) => {
options.lean = true;
options.new = true;
Models.findOneAndUpdate(criteria, dataToSet, options)
.then(client => resolve(client))
.catch(err => reject(err));
});
const deleteUser = criteria =>
new Promise((resolve, reject) => {
Models.findOneAndRemove(criteria)
.exec()
.then(client => resolve(client))
.catch(err => reject(err));
});
module.exports = {
updateUser: updateUser,
createUser: createUser,
deleteUser: deleteUser,
getUsers: getUsers
};
In the above file, There are common methods for database related task.
You can download complete code from this page to work the stuff at your end. Once you will complete with all the needed task, API will work like below(see the postman snapshot).
Registration API
Login API
Conclusion
So in this article, I explained how to start Creating APIs in Nodejs with Async/Await. If you are new to Node.js then click here find many demos to start the app for enterprise-level application
Let me know your thoughts over the email demo.jsonworld@gmail.com. I would love to hear them and If you like this article, share with your friends.
Thanks!!