Start Creating APIs in Node.js with Async/Await

Pankaj Kumar - Jul 16 '23 - - Dev Community

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);

Enter fullscreen mode Exit fullscreen mode

Problem with Callbacks- Callback hell


functionOne(()=>{
  functionTwo(()=>{
    functionThree(()=>{
      functionFour(()=>{
        functionFive(()=>{
         --- perform some operations here
    ------------------------------
        })
      })
    })
  })
})

Enter fullscreen mode Exit fullscreen mode

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);
})

Enter fullscreen mode Exit fullscreen mode

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:

Image description

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"
  }
}

Enter fullscreen mode Exit fullscreen mode

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);
});

Enter fullscreen mode Exit fullscreen mode

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
}

Enter fullscreen mode Exit fullscreen mode

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
};

Enter fullscreen mode Exit fullscreen mode

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).

**
Image description**

Login API

Image description

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!!

This article is originally posted over jsonworld

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .