Backend: Nodejs, Mongodb, Express Typescript
Tags: mongodb, typescript, express, node
Published: 2022-03-12 14:04:38

## Back-end with Node.js & MongoDB

**Overview**
Express and Node make up the middle (application) tier. Express.js is a server-side web framework, and Node.js the popular and powerful JavaScript server platform.
![Mern architecture](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pjmlkrbahbklhl90ve44.png)

**Express.js and Node.js Server Tier**
Express.js bills itself as a “fast, unopinionated, minimalist web framework for Node.js,” and that is indeed exactly what it is. Express.js has powerful models for URL routing (matching an incoming URL with a server function), and handling HTTP requests and responses.

By making XML HTTP Requests (XHRs) or GETs or POSTs from your React.js front-end, you can connect to Express.js functions that power your application. Those functions in turn use MongoDB’s Node.js drivers, either via callbacks for using Promises, to access and update data in your MongoDB database.

---

**Overview**

![Structure](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qy8lwrfj44xx0y816j6c.png)

- Via **Express** routes, HTTP request that matches a route will be checked by CORS Middleware before coming to Security layer.

- **Security layer** includes:
     1. JWT Authentication Middleware: verify SignUp, verify token
     2. Authorization Middleware: check User’s roles with record 
        in MongoDB database
     3. An error message will be sent as HTTP response to Client 
        when the middleware throw any error

- **Controllers** interact with MongoDB Database via Mongoose library and send HTTP response to Client.

**Packages**

- Express
- bcryptjs 
- jsonwebtoken 
- mongoose
- MongoDB
- cors

---
### Project
First create a 'backend' folder that we created previously and create the server. Then, we will initialize package.json using npm init.

```bash
 mkdir backend
 cd backend
 npm init- y
```
#### Project Structure
Install the required packages using npm or yarn. Since I am using Typescript the types are installed as dev dependencies. The package.json should look like this.

```json
packages
"dependencies": {
    "bcryptjs": "^2.4.3",
    "body-parser": "^1.19.2",
    "cookie-parser": "^1.4.6",
    "cors": "^2.8.5",
    "dotenv": "^16.0.0",
    "express": "^4.17.3",
    "express-jwt": "^6.1.1",
    "jsonwebtoken": "^8.5.1",
    "mongodb": "^4.4.1",
    "mongoose": "^6.2.4",
    "morgan": "^1.10.0"
  },
  "devDependencies": {
    "@types/bcryptjs": "^2.4.2",
    "@types/cookie-parser": "^1.4.2",
    "@types/cors": "^2.8.12",
    "@types/express": "^4.17.13",
    "@types/express-jwt": "^6.0.4",
    "@types/jsonwebtoken": "^8.5.8",
    "@types/mongoose": "^5.11.97",
    "@types/morgan": "^1.9.3",
    "@types/node": "^17.0.21",
    "nodemon": "^2.0.15",
    "ts-node": "^10.6.0",
    "typescript": "^4.6.2"
  }
```

1. **Folders**
Create the following folders
```bash
mkdir controllers routes middleware utils models config
touch server.ts config.env
```
– **_controllers_**
  auth.ts: handle signup & signin actions
  user.ts: return public & protected content
– **_routes_**
  auth.ts: POST register & login
  user.ts: GET public & protected resources
– **_middlewares_**
  auth.ts: Authentication middleware, check protected routes
  error.ts: error handling middleware
– **_models_** for Mongoose Models
  user.ts: User schema and model in Db
– **_config_**
  configure MongoDB database connection
  configure Auth Key
– **_server.ts_**: 
  import and initialize necessary modules and routes, listen for connections.
– **_config.env_**: 
  store environment variables

---

#### backend/server.ts
Here, we are requiring express and cors to be used. const port process.env.port will access the port variable from the config.env we required.
```typescript
require('dotenv').config({path:'./config.env'});

import express from "express";
import cors from "cors";
import cookieParser from 'cookie-parser';
import morgan from 'morgan';
import {json} from 'body-parser'
import mongoose from 'mongoose'
import { connectDB } from "./config/db";


 
const app= express();
const PORT= process.env.PORT || 5000;
const errorHandler = require('./middleware/error')

//connect to db
connectDB()

app.use(express.json());
app.use("/api/auth", require("./routes/auth"));
app.use("/api/private", require("./routes/private"));

//ErrorHandler (Should be last piece of middleware)
app.use(errorHandler);

const server=app.listen(
    PORT,()=>{
        console.log(`Server is running on port ${PORT}`)
    }
)
process.on("unhandledRejection",(error,promise)=>{
    console.log(`Logged Error: ${error}`);
    server.close(()=>process.exit(1))

})
```
---
#### backend/config.env
```typescript
PORT=5000
MONGO_URI=mongodb://localhost:27017/<your db name>
JWT_SECRET=<JWT secret key>
JWT_EXPIRE=10min
EMAIL_HOST=<Email config>
EMAIL_PORT= <Email config>
EMAIL_USER=<Email config>
EMAIL_PASS=<Email config>
EMAIL_FROM=<Email config>
```
---
#### backend/config/db.ts
Here we can add the following code to connect to our database. For this to work you should have mongodb installed and Mongodb Service started.
This function is used in **backend/server.ts** to connect to Mongodb

```typescript
import { ConnectOptions } from 'mongodb';
import mongoose from 'mongoose';
const connectDB = async ()=> {
    await mongoose.connect(process.env.MONGO_URI!);
    console.log('MongoDb Connected');   
}
module.exports=connectDB;
```

Upto now, we have a basic server that can connect to Mongodb. In the 3rd part of this series we will work on **Server API endpoints and Error Handling**