Node.js : REST API part 1
Tags: node, express, mongodb, tutorial
Published: 2020-09-07 14:31:37

Hello community,

in this tutorial, I'll teach you how to make REST API using Node.js.
we will cover all these topics :
* REST API: What is it, and what are its advantages?
* the idea of our project
* set up the environment
* choose the best structure for our project
* Build our REST API 

So let's get started 
## REST API: What is it, and what are its advantages?
REST API completely changed software engineering after 2000. This new approach to developing web projects and services was defined by Roy Fielding, father of the HTTP specification and one of the leading international authorities on everything to do with Network Architecture, in his dissertation entitled "Architectural Styles and the Design of Network-based Software Architectures".

Today, there are no projects or applications that don't have a REST API for the creation of professional services based on this software. Twitter, YouTube, Facebook identification systems… hundreds of companies generate business thanks to REST and REST APIs. Without them, any horizontal growth would be practically impossible. This is because REST is the most logical, efficient and widespread standard in the creation of APIs for Internet services.

## the idea of our project
in this tutorial, we will build a movies API :
* Register user
* Login user 
* create new movie (part 2)
* get all movies (part 2)
* get movie by ID (part 2)
* add movie  (part 2)
* update movie  (part 2)
* delete movie  (part 2)

## set up the environment 
technologies that we will use to build our API :
* Express : a Node.js framework 
* MongoDB : NoSQL database and we will use mongoose package 

open your cmd and type 
```
mkdir movies-api //create an empty folder
cd movies-api //navigate to our project 
npm init --yes //create package.json file 
npm i --save express
npm i --save mongoose 
npm i --save-dev nodemon 
```

## choose the best structure for our project
movies-api:
├───controllers
├───middleware
├───models
└───routes
so create these folders and let's get started the real work 

## the real work 
first, we need to create the index.js file 
go to your terminal and type
```
touch index.js
```
create our server 
````javascript
//index.js
const express = require('express');

const app = express();

const PORT = process.env.PORT || 5000;

app.listen(PORT, () => {
    console.log('server is running')
});
```
to run the server type in the terminal 
```
nodemon
```
you have to see something like that 
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/x7gqpce0ayeoflw79am1.PNG)

now it's the time to connect our project with database and for that i will use  [mongoDB atlas](https://www.mongodb.com/cloud/atlas) you can check it and make a free account
```javascript
//index.js
const express = require('express');
const mongoose = require('mongoose');

const app = express();

const PORT = process.env.PORT || 5000;


mongoose
  .connect(
    "your mongoDB atlas database url connection",
    { useUnifiedTopology: true, 
      useNewUrlParser: true, 
      useCreateIndex: true })
  .then(() => {
    app.listen(PORT, () =>console.log('server is running'))
  })
  .catch(err => {
    console.log(err);
  });
``` 
with this approach our server will run only if there is no error in the database connection.

the next step is to build the user model so create file in the models folder user-model.js 
````javascript
//user-model.js
const mongoose = require('mongoose');

const Schema = mongoose.Schema;

const userSchema = new Schema({
  name: { type: String, required: true },
  email: { type: String, required: true, unique: true },
  password: { type: String, required: true, minlength: 6 }
});

module.exports = mongoose.model('User', userSchema);
```

now let's make our user-controller in controllers folder we create file with name "user-controller.js" will contain two functions register and login.
But first we need three packages [bcryptjs](https://www.npmjs.com/package/bcryptjs), [jsonwebtoken](https://jwt.io/) and [express-validator](https://express-validator.github.io/docs/)
* bcryptjs : will help us to crypt the user password before store it in the database 
* jsonwebtoken : A JWT technically is a mechanism to verify the owner of some JSON data. It’s an encoded string, which is URL safe, that can contain an unlimited amount of data (unlike a cookie), and it’s cryptographically signed.
* express-validator : we need this package to test the data before we store it in the database.
```
npm i --save bcryptjs
npm i --save jsonwebtoken
npm i --save express-validator
```
note : you can install the three packages by one command 
```
npm i --save becryptjs jsonwebtoken express-validator
```

let's import our packages
````javascript 
//user-controller
const { validationResult } = require('express-validator');
const User = require('../models/user');
const bcrypt = require('bcryptjs');
const jwt = require('jsonwebtoken');
```

register function 
```javascript
//user-controller.js
const register = async (req,res) => {
 const errors = validationResult(req);

  if (!errors.isEmpty()) 
   return res.status(400).json("check your data");

  const { name, email, password } = req.body;
   let  existingUser = await User.findOne({ email: email });
   if (existingUser)
     return res.status(400).json("user exist");

  let hashedPassword = await bcrypt.hash(password, 12);

  const createdUser = new User({
    name,
    email,
    password: hashedPassword
});

  try { await createdUser.save() } catch (err) {}

  let token;
  token = jwt.sign(
    { userId: createdUser.id, email: createdUser.email },
    'supersecretkey',
    { expiresIn: '1h' });
    res.status(201).json({ token: token, userId: createdUser.id });
}


```

login function

```javascript
//user-controller.js
const login = async (req, res) => {
  const { email, password } = req.body;
  let existingUser;

  try {
    existingUser = await User.findOne({ email: email });
  } catch (err) { }

  if (!existingUser) 
    return res.status(200).json('Invalid credentials, could not log you in');

 let isValidPassword = await bcrypt.compare(password, existingUser.password);

  if (!isValidPassword) 
    return res.status(400).json('Invalid credentials, could not log you in.');

  let token;
  token = jwt.sign(
    { userId: existingUser.id, email: existingUser.email },
    'supersecretkey',
    { expiresIn: '1h' }
  );
  res.status(200).json({ token: token, userId: existingUser.id });
}
```
we need to export these two functions 
```javascript
//user-controller.js
exports.register= register;
exports.login = login;
```

with that we can start making the user routes so in the routes folder create new file "user-routes.js" this file will contain two routes one for register user and one for login user.

first let's import what we need   
```javascript
//user-rotes.js
const { check } = require('express-validator');
const usersController = require('../controllers/user-controller');
const express = require('express');
const router = express.Router();
```
Register Route 
````javascript
router.post('/register',
  [ check('name').not().isEmpty(),
    check('email').normalizeEmail().isEmail(),
    check('password').isLength({ min: 6 })],
usersController.register)
```
login Route 
````javascript
router.post('/login',
  [ check('email').normalizeEmail().isEmail(),
    check('password').isLength({ min: 6 })],
usersController.login)
```
export routes
````javascript
module.exports = router;
```
the last thing we need to do is to import user-routes to index.js and test our API with [postman](https://www.postman.com/)
```javascript
//index.js
const express = require('express');
const mongoose = require('mongoose');
const usersRoutes = require('./routes/user-routes');
const bodyParser = require('body-parser');

const app = express();
app.use(bodyParser.json());

app.use('/api/users', usersRoutes);

const PORT = process.env.PORT || 5000;
mongoose
  .connect(
    "your mongoDB atlas database url connection",
    { useUnifiedTopology: true, 
      useNewUrlParser: true, 
      useCreateIndex: true })
  .then(() => {
    app.listen(PORT, () =>console.log('server is running'))
  })
  .catch(err => {
    console.log(err);
  });
```
now open postman and start test login and register routes 
### Register 
choose the post method and type "localhost:5000/api/users/register" then go to body choose "row" then choose "json" finally enter your data and click send 

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/1tqfhe79n7ucxi1bkzuy.PNG)

### Login 
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/c5soex8xx64tm33oq30o.PNG)

open your database, you have to see a new user in users collection 
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/wajgx2i5svva63a6nju7.PNG)

We can say that our part 1 is done, we will continue in the next part.
Thank you.