DEV Community

SangeetaGogoi
SangeetaGogoi

Posted on

REST API in Express (ES6)

What is a REST API

From Redhat
A REST API (also known as RESTful API) is an application programming interface (API or web API) that conforms to the constraints of REST architectural style and allows for interaction with RESTful web services. REST stands for representational state transfer and was created by computer scientist Roy Fielding.

To create a Nodejs project (for a runtime environment) we will create a folder called rest-api and run the command.

npm init - y

Enter fullscreen mode Exit fullscreen mode

Once that is done, we will install few packages

npm i --save express cors mongoose
Enter fullscreen mode Exit fullscreen mode

Discussing the packages

  • Express: It is used to write the main code for the REST API
  • Cors: Used to make requests from a different domain. Eg: Request from frontend which is hosted in http://localhost:3000 to the backend which is http://localhost:5000
  • Mongoose: Mongoose is an ORM package which we will need to communicate with MongoDB.

To run ES6 import code instead of require we will add this piece of code to our package.json

"type": "module"
Enter fullscreen mode Exit fullscreen mode

Paste the following code

import express from 'express';
import mongoose from 'mongoose';
import cors from 'cors';

import authRoutes from './auth.routes.js';

const app = express();
const port = process.env.PORT || 8000

app.use(express.urlencoded({ extended: true }))
app.use(express.json())
app.use(cors())

authRoutes(app);

mongoose.connect(process.env.mongoURI, {
    useNewUrlParser: true,
    useUnifiedTopology: true
}).then(() => {
    console.log("Connected to Database");
}).catch(err => {
    console.log('Could not connect to the database', err);
    process.exit();
});

app.listen(port, () => {
    console.log('Backend is running on port: ' + port)
})
Enter fullscreen mode Exit fullscreen mode

Explaining the code step by step

import express from 'express';
import mongoose from 'mongoose';
import cors from 'cors';
Enter fullscreen mode Exit fullscreen mode

First we are going to import the libraries that we have installed

import authRoutes from './auth.routes.js';
Enter fullscreen mode Exit fullscreen mode

Here we are importing a file, which we will create soon.

const app = express();
const port = process.env.PORT || 8000
Enter fullscreen mode Exit fullscreen mode

In the first line we are creating an instance of express to use through out the app
In the second line we are declaring a port variable to that takes value from an .env file or the value is 8000

app.use(express.urlencoded({ extended: true }))
app.use(express.json())
app.use(cors())
Enter fullscreen mode Exit fullscreen mode

app.use(express.urlencoded({extended: true })) is a method inbuilt in express to recognize the incoming Request Object as strings or arrays.

app.use(express.json()) is a method inbuilt in express to recognize the incoming Request Object as a JSON Object

app.use(cors()) is using cors as a middleware for incoming requests from a different origin.

authRoutes(app);
Enter fullscreen mode Exit fullscreen mode

authRoutes(app) here we calling authRoutes function passing the app instance.

mongoose.connect(process.env.mongoURI, {
    useNewUrlParser: true,
    useUnifiedTopology: true
}).then(() => {
    console.log("Connected to Database");
}).catch(err => {
    console.log('Could not connect to the database', err);
    process.exit();
});

app.listen(port, () => {
    console.log('Backend is running on port: ' + port)
})
Enter fullscreen mode Exit fullscreen mode

These lines of code are used to connect to the mongodb and also check if it's running on which port.

import { register, login } from './auth.controller.js';

const authRoutes = (app) => {
  app.route('/register')
    .post(register)
  app.route('/signin')
    .post(login)
}

export default authRoutes
Enter fullscreen mode Exit fullscreen mode

Here we are routing the requests based on the method that is incoming.

import bcrypt from 'bcryptjs';
import User from './User.model.js';

export const register = (req, res) => {
  const { email, password, name, dob, gender } = req.body.userDetails
  const userData = {
    email, password, name, dob, gender
  }
  if (!email || !password || !name) {
    return res.status(422).json({ error: "Please add all the credentials" })
  }
  User.findOne({ email })
    .then((data) => {
      if (data) {
        res.send({ error: 'Email already registered' });
      } else {
        bcrypt.hash(password, 10, (err, hash) => {
          userData.password = hash;
          User.create(userData, (err, data) => {
            res.status(200).json({ msg: 'Successfully registered' });
          })
        })
      }
    })
    .catch((err) => res.send({ error: err }))
};

export const login = (req, res) => {

  const { email, password } = req.body.userDetails;
  User.findOne({ email: email })
    .then((user) => {
      if (!user) {
        res.send({ error: 'Account not found' })
      } else {
        if (!bcrypt.compareSync(password, user.password)) {
          res.send({ error: "You entered a wrong password" })
        } else if (bcrypt.compareSync(password, user.password)) {
          delete user.password;
          res.status(200).json({ user: user.toJSON() });

        }
      }
    })
    .catch((err) => res.json({ error: err }))
}
Enter fullscreen mode Exit fullscreen mode

I will not go into the details too much but here we have written two function for login and register.

While registering we are doing basic check if email, password and name are present or not. Before registering to our app, we will check if he is already present or not in the database. If he isn't present we will register him and use bcrypt to encrypt his password and save to database.

While logging in we are checking if the user is present or not. If not, we send an 'Account not found' error. If present, we pull out his data from database, remove his password and send back the data to the frontend.

import mongoose from 'mongoose';

const Schema = mongoose.Schema;

const UserSchema = Schema({
  name: {
    type: String,
    maxlength: 50,
  },
  email: {
    type: String,
    trim: true,
    unique: true,
    required: true,
  },
  password: {
    type: String,
    required: true,
  },
  gender: {
    type: String
  },
  dob: {
    type: Date
  }
})

const User = mongoose.model('User', UserSchema)
export default User;
Enter fullscreen mode Exit fullscreen mode

Lastly, this is the User schema for all the users.

Discussion (0)