DEV Community

Cover image for Backend: Nodejs, Mongodb, Express Typescript
Osiroski
Osiroski

Posted on

Backend: Nodejs, Mongodb, Express Typescript

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

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

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

 mkdir backend
 cd backend
 npm init- y
Enter fullscreen mode Exit fullscreen mode

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.

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"
  }
Enter fullscreen mode Exit fullscreen mode
  1. Folders Create the following folders
mkdir controllers routes middleware utils models config
touch server.ts config.env
Enter fullscreen mode Exit fullscreen mode

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.

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

})
Enter fullscreen mode Exit fullscreen mode

backend/config.env

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>
Enter fullscreen mode Exit fullscreen mode

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

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;
Enter fullscreen mode Exit fullscreen mode

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

Top comments (2)

Collapse
 
aliirz profile image
Ali Raza

I ran into an issue with the db.ts file. got an error on

module.exports=connectDB;

here is how i fixed it:
import { ConnectOptions } from 'mongodb';
import mongoose from 'mongoose';
const connectDB = async ()=> {
await mongoose.connect(process.env.MONGO_URI!);
console.log('MongoDb Connected');
}
export default connectDB;

Collapse
 
incredibledev1801 profile image
IncredibleDev1801

Some files of the project were not described.