Documentation

Express Node.js Server

Welcome to this beautiful Express server documentation.


  • Created: 01 January, 2024
  • Updated: 10 October, 2024

If you have any questions that are beyond the scope of this help file, Please feel free to email via Item Support Page .


Installation Process

Before installing Express server, Make sure you have already downloaded lastest Node.js

  1. Run the following command to install the required dependencies:
    npx node-expressx
  2. Now Open this project in vscode
  3. Create a new database in MongoDB Cloud Storage or Open MongoDB Compass for locally.
  4. Update the .env file with your database URL. By default, the database name is set to nextjs, but you can change it to whatever you prefer.

  5. You can configure both local and cloud databases for production-level deployment.
  6. Create a new table named users in MongoDB with the following fields:
    
    {
        "username": "",
        "email": "",
        "password": "",
        "role": ""
    }
                  
  7. Go to the project directory and open two terminal windows. In the first terminal, run the following command to start TypeScript compilation:
    npx tsc --w
    In the second terminal, start the project by running:
    npm start
  8. The project will now run on the following port:
    http://localhost:5000
  9. Open Postman and use the following API endpoint to create a new user:
    http://localhost:5000/api/v1/users

    Inside Postman: - Select the POST method. - Set the format to JSON. - Paste the following data into the body section:
    
      {
          "username": "Minhazul Abedin Munna",
          "email": "munna@gmail.com",
          "password": "1234",
          "role": "admin"
      }
                      

    - Used bcrypt to encrypt the password. - Then hit the Send button, and it will successfully create a new user.

API Endpoints

  • Base API:
    http://localhost:5000
  • User API:
                      
                      GET  http://localhost:5000/api/v1/users
                      POST  http://localhost:5000/api/v1/users
                      
                    

Folder Structure

Below is the folder structure for this server


              /node-server
              ├── /dist
              │   ├── /compiled_files
              ├── /node_modules
              ├── /src
              │   ├── /app
              │       ├── /lib
              │       ├── /middleware
              │       ├── /modules
              │       ├── /utils
              │           ├── /emailConfig  
              │           ├── /fileManagment
              │           ├── /paymentGateway
              │               ├── /sslCommerze
              │               ├── /stripe
              │       ├── app.ts
              │       ├── server.ts
              ├── /uploads
              │   ├── /audio
              │   ├── /files
              │   ├── /photos
              │   ├── /videos
              ├── .env
                  

Packages used

              
   - "cors"
   - "dotenv"
   - "express"
   - "jsonwebtoken"
   - "mongoose"
   - "nodemon"
   - "typescript"
   - "multer"
   - "sslcommerze"
   - "bcrypt"
   - "nodemailer"
   - "helmet"
   - "axios"
   - "imgbb"
   - "cloudinary"
              
            

Src Folder

Documentation and examples for Source folder

app.ts

              
import express, { Request, Response, NextFunction } from 'express'
import 'dotenv/config'
import cors from 'cors'
// Import your routes here
import { userRoutes } from './app/modules/user/user.route'
import helmet from 'helmet'
import { orderRoutes } from './app/modules/orders/orders.route'
import { orderController } from './app/modules/orders/orders.controller'

const app = express()

app.use(express.json())
app.use(cors())

// Helmet for Security purpose, hiding the 'Express' server name from Header
app.use(helmet());
app.use(helmet.crossOriginResourcePolicy({ policy: "cross-origin" }));

// Handling uploading the files to server
app.use('/uploads', express.static('uploads'))

/*
Payment Gateway redirection URL success, fail and cancel
Don't move after the cors policy, it will not work there.
Will show the response like Access Blocked.
*/
app.use('/success/:tranId', orderController.success)
app.use('/fail/:tranId', orderController.fail)
app.use('/cancel/:tranId', orderController.cancel)


// Allow only requests from a specific domain, frontend domain url eg. http://www.example.com
const allowedDomains = ['http://localhost:5173']; // You can add more domains by separating with comma.
// default React.js frontend local domain url
app.use(cors({
    origin: function (origin: any, callback) {
        if (allowedDomains.includes(origin) || !origin) {  // Allow if the request is from the allowed domain or if there's no origin (e.g., from Postman)
            callback(null, true)
        } else {
            callback(new Error('Access blocked: Unauthorized access!!!'))
        }
    },
    credentials: true, // Enable if you want to allow cookies with the request
}))

/*-------------------HANDLE ALL OF YOUR ROUTES HERE ----------------------*/

app.use('/api/v1/users', userRoutes) //users routes
app.use('/api/v1/orders', orderRoutes) //orders routes

/*-------------------HANDLE ALL OF YOUR ROUTES HERE ----------------------*/


// Home route json messages
app.get('/', (req: Request, res: Response) => {
    res.status(200).json({
        success: true,
        message: 'Welcome to Node.js Server',
        author: 'Minhazul Abedin Munna',
        github: 'https://github.com/smmunna',
        linkedin: 'https://www.linkedin.com/in/minhazulabedinmunna/',
    })
})

// Route Error for any  url not found
app.all('*', (req: Request, res: Response) => {
    res.status(404).json({
        status: 404,
        message: 'Not Found'
    })
})

// Global Error Handler
app.use((error: any, req: Request, res: Response, next: NextFunction) => {
    if (error) {
        res.status(500).send({
            success: false,
            message: error.message
        })
    }
})

export default app;
              
            

server.ts

            
//CREATE CONNECTION WITH MONGODB DATABASE
import mongoose from 'mongoose';
import app from './app'

async function main() {
    try {
        await mongoose.connect(`${process.env.DATABASE_URL}`)
        app.listen(process.env.PORT, () => {
            console.log(`Example app listening on port ${process.env.PORT}`)
        })
    } catch (error) {
        console.log(error)
    }
}

main()
            
           

.env

          
# AUTHOR: MINHAZUL ABEDIN MUNNA
# http://www.youtube.com/MinhazulAbedinMunna
# SERVER RUNNING PORT
#--------------------------------

# PORT=
# DATABASE_URL=mongodb+srv://:@cluster0.rvrwrto.mongodb.net/?retryWrites=true&w=majority
# DATABASE_URL=mongodb://127.0.0.1:27017/

PORT=5000
DATABASE_URL=mongodb://127.0.0.1:27017/nextjs
ACCESS_TOKEN_SECRET=faec720b28e76b3259e6ce95fdf3ab39956e5991ed4a24786527eb31948b8369a6460978f3e75a44d6bf9a3ec6ca91a9da7ba8c29794c3391872d081779ec8a1

# MAIL Configuration
#--------------------------------
MAIL_HOST=""
MAIL_PORT=
MAIL_USERNAME=""
MAIL_PASSWORD=""

# Payment Gateway Configuration
#--------------------------------

# SSL COMMERZE Configuration
STORE_ID=
STORE_PASSWORD=
IS_LIVE=false

# Backend function calling for success, failure, cancellation
PAYMENT_SUCCESS_URL=http://localhost:5000/success
PAYMENT_FAIL_URL=http://localhost:5000/fail
PAYMENT_CANCEL_URL=http://localhost:5000/cancel
PAYMENT_IPN_URL=http://localhost:5000/ipn

# Frontend url will show, this is example for react.js
FRONTEND_SUCCESS_URL=http://localhost:5173/success
FRONTEND_FAIL_URL=http://localhost:5173/fail
FRONTEND_CANCEL_URL=http://localhost:5173/cancel
FRONTEND_IPN_URL=http://localhost:5173/ipn

# Stripe Configuration
STRIPE_SECRET_KEY=""

# Paypal Configuration
PAYPAL_CLIENT_ID=""
PAYPAL_CLIENT_SECRET=""

# IMGBB API KEY
IMGBB_API_KEY =''

# CLOUDINARY API CONFIG
CLOUDINARY_CLOUD_NAME=''
CLOUDINARY_API_KEY=''
CLOUDINARY_API_SECRET=''
          
         

Modules Folder

It'll contains different modules, Here example given user module

orders module

Interface

In the interface, you have write down what will be your table columns

              
// Creating user interface with their fields and data type
interface User {
    username: string;
    email: string;
    password?: string;
    role?: string;
}

export default User;
              
            

Design Model

Design model according to your interface

              
import { Schema, model } from 'mongoose';
import User from './user.interface';
import bcrypt from 'bcrypt';

// Creating Schema
const userSchema = new Schema({
    username: { type: String, required: true },
    email: { type: String },
    password: { type: String, required: true },
    role: { type: String }
})

// Pre-save hook to hash the password
userSchema.pre('save', function (next) {
    const user = this as any;

    // Hash the password only if it's new or modified
    if (!user.isModified('password')) return next();

    bcrypt.hash(user.password, 10, (err, hash) => {
        if (err) return next(err);
        user.password = hash;
        next();
    });
});

// Creating a Model
const userModel = model('user', userSchema)

export default userModel;
              
            

Controller

Here controller used as a function. You have to export that function and call it from routes file.

              
import { NextFunction, Request, Response } from "express";
import { UserService } from "./user.service";
import userModel from "./user.model";
import sendApiResponse from "../../lib/ApiResponse/sendApiResponse";

// Create user
const createUser = async (req: Request, res: Response, next: NextFunction) => {
    try {
        const user = req.body;
        const result = await UserService.createUserToDB(user)
        sendApiResponse(res, 200, true, 'User created successfully', result)
    } catch (error) {
        next(error);
    }
}

// Get users
const getUsers = async (req: Request, res: Response, next: NextFunction) => {
    const result = await UserService.getAllUsers();
    sendApiResponse(res, 200, true, 'Users fetched successfully', result)
}

// These are accessible from different files.
export const userController = {
    createUser,
    getUsers
}
              
            

Service

In controller we can see UserService. That is from user.service.ts file. This is used to reduced the code from controller and database operation are moved to service file

Example of service file:

              
import User from "./user.interface"
import userModel from "./user.model"

// Creating new user
const createUserToDB = async (user: User) => {
    const result = await userModel.create(user)
    return result
}

// Getting all users
const getAllUsers = async () => {
    const users = await userModel.find({}, { password: 0, role: 0 }) //not showing password and role field
    return users
}

export const UserService = {
    createUserToDB,
    getAllUsers
}
              
            

Routes

Here is an example of two routes. We called the userController function to access the activity.

                
import express from "express";
import { userController } from "./user.controller";

const router = express.Router()

router.post('/', userController.createUser)
router.get('/', userController.getUsers)


// Redirect URL will be in app.ts file, Here redirect URL will not work


export const userRoutes = router;
                
              

Then we will use this file in app.ts file for acessing the routes. Follow this:

                
// Import your routes here
import { userRoutes } from './app/modules/user/user.route'

// Route handlings;
app.use('/api/v1/users', userRoutes)
                
              

Route path now: http://localhost:5000/api/v1/users


Complete Express Server Tuitorials

Documentation Video

Here is the complete documentation in video, This will help you to setup the Express Server

1. Setup Express Server

2. Folder Structure

3. Modular Pattern

4. Authentication with JWT

4. File Upload (Photo, audio, video, doc, xlsx, pdf)

4. Payment Gateway (sslCommerze, stripe, paypal)

4. Email Configuration