How to build movie rental app using NodeJs REST API with express and mongoDB - ES6 version. part-1
Published: 2023-06-11 19:22:18

## Introduction

Welcome to our comprehensive guide on building your very own movie rental app! In this tutorial, we will walk you through the process of creating a movie app from scratch. By the end of this guide, you will have the knowledge and skills to develop an app that allows movie owners to list their available titles and enables customers to easily rent and enjoy their favorite movies.

REST is an acronym for Representational State Transfer. Rest follows some guidelines to facilitate the communication between systems. in this post we will learn how to build movie rental app using REST API with NodeJs and MongoDB database, all the code are written in ES6. First, we will see how to setup boiler plate project with Express framework and configure the our app to use es6. after we will create http server and finally configure the NodeJS application to read data from the MongoDB database.

## prerequisites 

- _<u>NodeJs</u>_
- _<u>ExpressFramework</u>_
- _<u>MongoDB</u>_
- _<u>Babel</u>_
- _<u>VsCode</u>_
- _<u>Swagger</u>_
- _<u>Postman</u>_
- _<u>nodemon</u>_
- _<u>dotenv</u>_

**_NodeJS:_**As an asynchronous event-driven JavaScript runtime, Node.js is designed to build scalable network applications.

**_Express Framework:_** Express is a minimal and flexible Node.js web application framework that provides a robust set of features for web and mobile applications.

**_MongoDB:_**is an open-source, cross-platform, and distributed document-based database designed for ease of application development and scaling. It is a NoSQL database developed by MongoDB Inc.

**_Babel:_**is a toolchain that is mainly used to convert ECMAScript 2015+ code into a backwards compatible version of JavaScript in current and older browsers or environments.

**_VSCode_**:The editor we are using for the project. [It’s open-source and you can download it here](https://code.visualstudio.com/Download).

**_Swagger_**: API documentation.

**_Postman_**: API Testing.

**_nodemon_**: To speed up the development.

**_dotenv_**: The dotenv package is a great way to keep passwords, API keys, and other sensitive data out of your code. It allows you to create environment variables in a . env file instead of putting them in your code.

If you are new to NodeJS and don’t know how to build REST API with it, I would recommend going through this article.write all the code with your hand and avoid copy pasting.

**Project Link**
Here is the Github link for the our project you can just clone and run on your machine.

```
https://github.com/leandreAlly/Movio.git
```
Fist let's create the folder structure of our project.
create a folder and call it `Movio` or whatever the name.
open that folder in command line. then excute the following command to easily create the project structure.
`mkdir src`
`cd src`
`mkdir config controllers documents middlewares model routes services utils validations `

after successful execution of above commands the next is back the movio directory by running the `cd ..` command.

**Install package manager(NPM)**
npm is package manager which is going to help us to manage depencies.
to start working with npm you need to run `npm init -y` we added flag -y to accept all default options.
more explanation of npm init you can [read this article](https://careerkarma.com/blog/npm-init/)

Boom! you're on the track!
let's install our package we're going to use in the projects.
simply run this command in your terminal

```
npm install express mongoose dotenv joi @babel/core @babel/node @babel/preset-env morgan colors
```
create the .env file to hold our environment variables.

**Babel configuration**
as i said above the babel is toolchain which help us to transipile our code from ECMAScript 2015+ code into a backwards compatible version of JavaScript. and in this project our code will be written in ES6.

create a file `.babelrc` in parent directory and this code for configuration.

```
{
    "presets": [
      "@babel/preset-env"
  ],
      "env": {
        "test": {
          "plugins": ["@babel/plugin-transform-modules-commonjs"]
        }
      }
    }
```
after your project should look like this 

![Project structure](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fh6a82dvks0k5nl8bbtj.png)

it's time for building! navigate to the `src` folder.
create the files `app.js` and `server.js`
in app.js add this code

```
import express from "express";
import morgan from "morgan";

const app = express();

app.use(morgan("combined"));
app.use(express.json());

app.get("/", (req, res) => {
  return res.status(200).json({ message: "Welcome to my Movio App" });
});

export default app;
```
before we setup our express let's first configure our app to work with mongoDB by using mongoose as DB engine.

go into `src/services` and create the file which is called `mongo.js`.
add this code into mongo.js

```
import mongoose from "mongoose";
import color from "colors";
import dotenv from "dotenv";

dotenv.config();

const DB_URL = process.env.MONGO_URL;

mongoose.connection.once("open", () => {
  console.log("Database Connected!".blue.underline);
});

const mongoConnect = async () => {
  await mongoose.connect(DB_URL);
};

const mongoDisconnect = async () => {
  await mongoose.disconnect();
};

export { mongoConnect, mongoDisconnect };
```
it's time to for our express server setup.
go into server.js and add this code. 

```
import http from "http";
import dotenv from "dotenv";
import { mongoConnect } from "./services/mongo";
import app from "./app";

dotenv.config();

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

const server = http.createServer(app);

const startServer = async () => {
  mongoConnect();
  server.listen(PORT, () => {
    console.log(`Server is running on port ${PORT}`);
  });
};

startServer();

```

`Test early, test often` ~Kent Beck
at this stage let's test our app, but wait? we need to create the script for starting our app in package.json file.
header over to package json and this script for development. 

```
"dev": "nodemon --exec npx babel-node src/server"
```
after your package.json file should look like this--->

```
{
  "name": "movio",
  "version": "1.0.0",
  "description": "",
  "main": "server.js",
  "scripts": {
    "start": "node src/server.js",
    "dev": "nodemon --exec npx babel-node src/server"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "@babel/core": "^7.21.8",
    "@babel/node": "^7.20.7",
    "@babel/preset-env": "^7.21.5",
    "colors": "^1.4.0",
    "dotenv": "^16.0.3",
    "express": "^4.18.2",
    "joi": "^17.9.2",
    "mongoose": "^7.1.1",
    "morgan": "^1.10.0"
  },
  "devDependencies": {
    "nodemon": "^2.0.22"
  }
}

```
at this time we don't even need postman, also you can use browser. first run this script in your terminal `npm run dev` and add this your url in tab `http://localhost:<PORT>`

I hope you have this results:

![Test home endpoints](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4gzcbubzt8sqd364jprx.png)

Now our server is working it's time start building our `Movio` app.
when it comes to software building developers have different approach but on my opinion the best approach I have ever found is first design your database model. 
without delaying let's start by desgning our first model of movie `genre`

go to model folder and create the file which is called `genre.js`
add this code into genre.js 

```
import mongoose from "mongoose";

const genreSchema = new mongoose.Schema({
  name: {
    type: String,
    required: true,
    minlength: 5,
    maxlength: 50,
  },
});

const Genre = mongoose.model("Genre", genreSchema);

export { Genre };
```
after creating the database schema it's time to build our controller, so add file in controller folder which is called `genre.controller.js`
insert this code into `genre.controller.js`

```
import { Genre } from "../model/genre";
const addGenre = async (req, res) => {
  try {
    const { name } = req.body;
    let genre = new Genre({
      name,
    });
    await genre.save();

    return res.status(201).json({ message: "Genre created successful", genre });
  } catch (err) {
    return res.status(500).json({ error: err, message: "Server error" });
  }
};

export { addGenre };
```
this is controller for creating out genre. 
let's connect this controller with our routes.
go into routes folder and create another foldr inside and call it `api ` this is going to contain all files for our endpoints. create the file inside `api` folder call it `genre.routes.js` all routes related to genre are going to be holded by this file.
add this code in this file you created.

```
import { Router } from "express";
import { addGenre } from "../../controlllers/genre.controller";

const route = Router();

route.post("/", addGenre);

export default route;
```
now we have routes for adding genre using POST method the next is to give this routes specific endpoints, create the file `index.js`  in routes folder which is going to provide endpoint for all our routes and insert this code.

```
import { Router } from "express";
import genre from "../routes/api/genre.routes";

const routes = Router();

routes.use("/genre", genre);
export default routes;
```
we're good way to go for completing this endpoints now we have everything the only thing remained is app base Url.

go into `app.js` and update it by provide base url into our app, here is updated `app.js`

```
import express, { application } from "express";
import morgan from "morgan";
import allRoutes from "./routes/index";//new line for import all endpoints

const app = express();

app.use(morgan("combined"));
app.use(express.json());

app.use("/api/v1", allRoutes);// create the base url
app.get("/", (req, res) => {
  return res.status(200).json({ message: "Welcome to my Movio App" });
});

export default app;
```

Now our genre endpoint is working correctly, let's documents our api using swagger.

first we need to install swagger package which going to help us to configure our app, run this command in your terminal 

```
npm i swagger-jsdoc swagger-ui-express 
```
after you package is installed let's create a file that will hold our endpoints documentation. in `src`  directory create a file which is called `swagger.js` and add this code in it.

```
import dotenv from "dotenv/config";
import { addGenre } from "./documents/genre.docs";

export const swaggerDocument = {
  openapi: "3.0.1",
  info: {
    version: "1.0.0",
    title: "Movio APIs Document",
    description:
      "Movio: an movie app for renting and listing Movie in the store",
    termsOfService: "",
    contact: {
      name: "Leandre",//add your name
      email: "tuyambazeleandre@gmail.com",//replace this with your email
      url: "https://leandredev.netlify.app/",//add yout website link
    },
  },
  servers: [
    {
      url: `http://localhost:${process.env.PORT}`, // url
      description: "Local server", //
    },
    {
      url: "https://movio-api.onrender.com/", // url hosted version
      description: "Hosted version", // name
    },
  ],
  components: {
    securitySchemes: {
      bearerAuth: {
        type: "apiKey",
        name: "Authorization",
        scheme: "bearer",
        in: "header",
      },
    },
  },
  paths: {
    "/api/v1/genre": {
      post: addGenre,
    },
  },
};

```

after create this file the next is documents our endpoints. create a file in document directory and call it `genre.docs.js` , this is going to hold all documentation endpoints for genre Api, after add this code.

```
export const addGenre = {
  tags: ["Genre"],
  summary: "Create genre",
  description: "Create a movie genre",
  parameters: [],
  requestBody: {
    required: true,
    content: {
      "application/json": {
        schema: {
          type: "object",
          properties: {
            name: {
              type: "string",
              required: true,
            },
          },
          example: {
            name: "Romantic",
          },
        },
      },
    },
  },
  consumes: ["application/json"],
  responses: {
    201: {
      description: "Genre added successfull",
    },

    500: {
      description: "Server error",
    },
  },
};

```
After completing this task the is to configure our swagger in main `app.js`, now update this file with this code.

```
import express, { application } from "express";
import morgan from "morgan";
import swaggerUi from "swagger-ui-express";//import of swagger
import allRoutes from "./routes/index";
import { swaggerDocument } from "./swagger";//import our base file for endpoints documentation

const app = express();

app.use(morgan("combined"));
app.use(express.json());

app.use("/api-docs", swaggerUi.serve, swaggerUi.setup(swaggerDocument));//setup swagger endpoints
app.use("/api/v1", allRoutes);
app.get("/", (req, res) => {
  return res.status(200).json({ message: "Welcome to my Movio App" });
});

export default app;

```
to test this navigate to `http://localhost:<PORT>`/api-docs

I hope you have this result:

![swagger testing](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6nwf88a5i4pawmkhpfzs.png)


Now you have successful completed to build the create genre endpoints, I have tried show every step for building this endpoints. In case you encounter with some error you post them in comments and I will try to come up with solution. 

Practice makes perfect---->
Exercise: Try to build the getting all genre endpoints and documents it with swagger and you will find solution in part2 which I will release soon. 

**Conclusion**

We have seen how to set up MongoDB and Babel and configure it in NodeJS API written in ES6. In future posts, we will see how to build another genre customer endpoint and put  and many more.