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.
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
Via Express routes, HTTP request that matches a route will be checked by CORS Middleware before coming to Security layer.
-
Security layer includes:
- JWT Authentication Middleware: verify SignUp, verify token
- Authorization Middleware: check User’s roles with record in MongoDB database
- 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
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"
}
- Folders Create the following folders
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.
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
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
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
Top comments (2)
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;
Some files of the project were not described.