Giter Site home page Giter Site logo

assacc02's Introduction

Backend Environment & Database connection

Environment Setup : Folder বানানো + mongodb, mongoose, dotenv, express etc connect করে project এর foundation ready করা

  1. "ExpressBoilerTemplate" নামের একটা parent-folder বানাতে হবে যার ভিতরে আরো দুটা folder বানাতে হবে "ExpressBoilerTemplate/frontend" & "ExpressBoilerTemplate/backend"
  2. backend folder এর ভিতরে দুটা file বানাতে হবে "ExpressBoilerTemplate/backend/server.js" & "ExpressBoilerTemplate/backend/app.js"
  3. এবার terminal দিয়ে "ExpressBoilerTemplate" folder এ npm init command দিতে হবে, package name দিতে হবে ExpressBoilerTemplate, entry point দিতে হবে backend/server.js বাদ বাকি সব step ok ok করে দিতে হবে

npm init
package name : ExpressBoilerTemplate
entry point : backend/server.js

  1. আবারো terminal দিয়ে "ExpressBoilerTemplate" folder এ npm দিয়ে express, mongoose, dotenv, cors install করতে হবে

npm i express mongoose dotenv cors

  1. এবার "ExpressBoilerTemplate/backend/app.js" file এ express, cors কে import করে তা দিয়ে app বানিয়ে app.use() method দিয়ে cors() & express.json() function কে invoke করে তারপর app কে এই file থেকে export করে দিয়ে হবে যাতে অন্য file থেকেও এই app টার access পাওয়া যায়

[[FILENAME : ExpressBoilerTemplate/backend/app.js]]
"""""""""""""""""""""""""""""""""""""""""""
const express = require("express");
const cors = require('cors')
const app = express();
app.use(cors())
app.use(express.json())
module.exports = app;

  1. এবার backend folder এ একটা config নামের folder বানাতে হবে "ExpressBoilerTemplate/backend/config" তার ভিতরে একটা .env file বানাতে হবে "ExpressBoilerTemplate/backend/config/config.env" এবং এই file এ একটা PORT নামের environment variable বানাতে হবে

[[FILENAME : ExpressBoilerTemplate/backend/config/config.env]]
""""""""""""""""""""""""""""""""""""""""""""""""""""""
PORT=5000

  1. এবার "ExpressBoilerTemplate/backend/server.js" file এ app, dotenv কে import করে নিতে হবে, তারপর dotenv কে file এর সাথে connect করে নিতে হবে (line: 4) এবং app.listen() method দিয়ে একটা server establish করতে হবে

[[FILENAME : ExpressBoilerTemplate/backend/server.js]]
""""""""""""""""""""""""""""""""""""""""""""""
const app = require("./app");
const dotenv  = require("dotenv")
//config
dotenv.config({ path: "backend/config/config.env" });
app.listen(process.env.PORT, () => {
  console.log(`Server is working on http://localhost:${process.env.PORT}`);
});

  1. এবার nodemon দিয়ে server কে run করার জন্য start & start-dev scrip add করতে হবে "ExpressBoilerTemplate/package.json" file এ

[[FILENAME : ExpressBoilerTemplate/package.json]]
"""""""""""""""""""""""""""""""""""""""""
"start": "node backend/server.js",
"start-dev": "nodemon backend/server.js",

Backend Route Test without DB Connected :

  1. backend folder এ দুটা নতুন folder বানাতে হবে "ExpressBoilerTemplate/backend/controllers" & "ExpressBoilerTemplate/backend/routes" তারপর controllers folder এ users এর জন্য একটা file বানাতে হবে "ExpressBoilerTemplate/backend/controllers/usersController.js" ।

এই contoller file গুলো মূলত API এর async function কে hold করে

  1. usersController API এর জন্য getAllUsers function বানাতে হবে যা inline exported হবে

[[FILENAME : ExpressBoilerTemplate/backend/controllers/usersController.js]]
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
// Get All Product
exports.getAllUsers = (req, res) => {
  res.status(200).json({
    success: true,
    message: "getAllUsers route is working",
  });
});

  1. এবার "ExpressBoilerTemplate/backend/routes" folder এ _getAllUsers function_ কে get request দিয়ে routing করার জন্য জন্য একটা file বানাতে হবে "ExpressBoilerTemplate/backend/routes/usersRoutes.js"
  2. "ExpressBoilerTemplate/backend/routes/usersRoutes.js" file এ express, getAllUsers কে import করে express এর সাহায্যে express.Router() method দিয়ে router create করতে হবে, এরপর router.route().get() method দিয়ে প্রতিটা API requests এর aginst এ route বানাতে হবে এবং সবার নিচে router কে exports করে দিতে হবে ।

এখানে মূলত সকল APIs এর জন্য যে http req আছে যেমন .get, .post, .put, .delete আছে সেগুলোকে pathName অনুযায়ি line by line declare করা হয় এবং pathName যদি same হয় তাহলে সবগুলো request কে একই line এও declare করা যায়

[[FILENAME : ExpressBoilerTemplate/backend/routes/usersRoutes.js]]
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
const express = require("express");
const { getAllUsers } = require("../controllers/usersController");



const router = express.Router();



router.route("/all").get(getAllUsers);







module.exports = router;

  1. এবার "ExpressBoilerTemplate/backend/app.js" file এ usersRoutes variable কে import করে তারপর app.use() method দিয়ে commonURL & usersRoutes সহ invoke করতে হবে।

এই commonURL সব সময় url এর সাথে fixed থাকে

এখানে commonURL হচ্ছে "/user"

পাশাপাশি এখানে NOT FOUND route বানিয়ে দেয়া হয়েছে যাতে যেকোন ভুল লিঙ্ক এ req দিলে যাতে error না খেয়ে একটা meaningfull message আসে

[[FILENAME : ExpressBoilerTemplate/backend/app.js]]
"""""""""""""""""""""""""""""""""""""""""""
const express = require("express");
const cors = require('cors')


const app = express();


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


//Route imports
const usersRouter = require('./routes/usersRoutes');



//invoking routes
app.use('/user', usersRouter);


// Not found route
app.all("*", (req, res) => {
    res.send("NO route found.");
});




module.exports = app;

  1. এবার nodemon দিয়ে project run করার জন্য terminal দিয়ে "ExpressBoilerTemplate" folder এ npm run start-dev command দিতে হবে

[[FOLDERNAME : ExpressBoilerTemplate]]
""""""""""""""""""""""""""""""
npm run start-dev

  1. এবার postman software দিয়ে project test করার জন্য Ecommerce নামের একটা নতুন collection বানাতে হবে, তারপর সেখানে http://localhost:5000/user/all link এর against এ একটা GET request generate করতে হবে

postman success screenshot

Connect Database :

  1. প্রথমে "ExpressBoilerTemplate/backend/config/config.env" file এ DB_URI নামের আরো একটা environment variable বানাতে হবে

এই DB_URI টা MongoCompass এর জন্য কেবল অর্থাৎ যখন direct mongoDB তে database connenct করা হবে তখন কিন্তু এইটাকে change করে mongoDB database এর DB_URI ব্যবহার করতে হবে

[[FILENAME : ExpressBoilerTemplate/backend/config/config.env]]
""""""""""""""""""""""""""""""""""""""""""""""""""""""
PORT=5000
DB_URI="mongodb://localhost:27017/Ecommerce"

  1. Database connect করার জন্য "ExpressBoilerTemplate/backend/config/database.js" নামের একটা file বানাতে হবে, তারপর সেখানে mongoose কে import করে নিতে হুবে, এবার connectDatabase function এ নিচে দেখানো code এর মত করে database connect করে সবার নিচে connectDatabase কে এখান থেকে export করে দিতে হবে

তবে মনে রাখতে হবে বর্তমান version এ useCreateIndex: true লিখলে *error দেয় তাই এই line টাকে comment out করে দিতে হবে

[[FILENAME : ExpressBoilerTemplate/backend/config/database.js]]
""""""""""""""""""""""""""""""""""""""""""""""""""""""
const mongoose = require("mongoose");
const connectDatabase = () => {
  mongoose
    .connect(process.env.DB_URI, {
      useNewUrlParser: true,
      useUnifiedTopology: true,
   // useCreateIndex: true, // this is not supported now
    })
    .then((data) => {
      console.log(`Mongodb connected with server: ${data.connection.host}`);
    })
    .catch((err) => {
        console.log(err);
    });
};
module.exports = connectDatabase;

  1. এবার "ExpressBoilerTemplate/backend/server.js" file এ connectDatabase function কে import করে invoke করে দিতে হবে

[[FILENAME : ExpressBoilerTemplate/backend/server.js]]
""""""""""""""""""""""""""""""""""""""""""""""
const app = require("./app");
const dotenv  = require("dotenv");
const connectDatabase = require("./config/database");
//config
dotenv.config({ path: "backend/config/config.env" });
// Connecting to database
connectDatabase();
app.listen(process.env.PORT, () => {
  console.log(`Server is working on http://localhost:${process.env.PORT}`);
});

Backend errorhandlling with node.js in built Error method

Handle Errors for : Wrong Mongodb Id, async error handleing, Mongoose duplicate key error, Wrong JWT, JWT EXPIRE error, http status code error

Handling Wrong Mongodb Id error

  1. এবার backend folder এর ভিতরে "ExpressBoilerTemplate/backend/utils" folder বানিয়ে তার ভিতরে একটা file বানাতে হবে "ExpressBoilerTemplate/backend/utils/errorhander.js" নামের
  2. এবার এখানে আমরা একটা js class generate করব ErrorHandler নামের যা inherited হবে node.js এর default Error Class feature থেকে , এরপর সবার নিচ থেকে ErrorHandler class টাকে export করে দিবা যাতে অন্যসব file থেকে এর সাহায্যে আমরা প্রয়োজনিয় error generate করতে পারি।

ErrorHandler class টাতে, constructor এর সাহায্যে আমরা error কে invoke করার সময় যে agrument হিসেবে message & statusCode পাঠাব তা recieve করব।

super এর সাহায্যে আমরা super or parent class অর্থাত "Error" Class এর message show করার যে default constructor আছে তাকে chile class ErrorHandlerinherrit করেছি

এখানে super বলতে মূলত parent class এর constructor কে বুঝায়

captureStackTrace হচ্ছে "Error" Class এর default function যাকে আমরা inherrit করেছি। এই captureStackTrace function ই মুলত কোন error আসলে তা আমাদের stack এ trace করে দেয় দুটা parameter এর সাহায্যে যার একটি হচ্ছে, (১) child class নিজেই এক্ষেত্রে "ErrorHandler" এবং ২য় হচ্ছে, (২) child class এর constructor

[[FILENAME : ExpressBoilerTemplate/backend/utils/errorhander.js]]
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
class ErrorHandler extends Error{
    constructor(message,statusCode){
        super(message);
        this.statusCode = statusCode
        Error.captureStackTrace(this,this.constructor);
    }
    
}
module.exports = ErrorHandler

  1. এবার এই erro কে conditionally implement করার জন্য আমাদের একটা middleware বানাতে হবে এজন্য, backend folder এর ভিতরে "ExpressBoilerTemplate/backend/middleware" folder বানিয়ে তার ভিতরে একটা file বানাতে হবে "ExpressBoilerTemplate/backend/middleware/error.js" নামের
  2. এই "ExpressBoilerTemplate/backend/middleware/error.js" file এ ErrorHandler কে import করি নিব , তারপর module.exports করব একটা callback function কে যা চারটি parameter নিবে err,req,res,next

এটা মূলত express.js এর default error handling method , extra হিসেবে just কিছু condition implement করা হয়েছে

[[FILENAME : ExpressBoilerTemplate/backend/middleware/error.js]]
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
const errorMiddleware = (err, req, res, next) => {
  err.statusCode = err.statusCode || 500;
  err.message = err.message || "Internal Server Error";
  
  res.status(err.statusCode).json({
    success: false,
    message: err.message,
  });
};
module.exports = errorMiddleware 

  1. এবার "ExpressBoilerTemplate/backend/app.js" file এ এই errorMiddleware কে import করে নিব, তারপর app.use() method এর সাহায্যে সর্ব শেষ middleware হিসেবে errorMiddleware কে রাখব

এটাই মূলত নিয়ম যে, errorMiddleware সবার last এ invoke করা থাকে যাতে অন্যকোন একটা middleware এ কোন সমস্যা হলে programm jump করা এই last middleware এ hit করবে তারপর error show করবে

[[FILENAME : ExpressBoilerTemplate/backend/app.js]]
"""""""""""""""""""""""""""""""""""""""""""
const express = require("express");
const cors = require('cors')
const errorMiddleware = require("./middleware/error");


const app = express();


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


//Route imports
const usersRouter = require('./routes/usersRoutes');



//invoking routes
app.use('/user', usersRouter);


// Not found route
app.all("*", (req, res) => {
    res.send("NO route found.");
});




// Middleware for Errors
app.use(errorMiddleware);


module.exports = app;

  1. এবার postman software এ test করব mongDb id last এর digit 9 কে অন্যকিছু দিয়ে replace করব

postman success screenshot

Handling asynchronus error


#### 8. এবার **_asynch error_** কে handle করার জন্য আরো একটা middleware বানাতে হবে ExpressBoilerTemplate/backend/middleware/**catchAsyncErrorsMiddleware.js** নামের,

এই middleware টা মূলত parameter হিসেবে একটা function কে recieve করবে তারপর javaScript এর default class Promise এর Promise.resolve().catch() method এর সাহায্যে যদি কোন error না থাকে তাহলে try করবে আর থাকলে catch করে next করবে

[[FILENAME : ExpressBoilerTemplate/backend/middleware/catchAsyncErrorsMiddleware.js]]
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
const catchAsyncErrorsMiddleware = (theFunc) => (req, res, next) => {
  Promise.resolve(theFunc(req, res, next)).catch(next);
};
module.exports = catchAsyncErrorsMiddleware

  1. এবার "ExpressBoilerTemplate/backend/controllers/usersController.js" file এ catchAsyncErrorsMiddleware কে import করে নিয়ে তারপর সবগুলো asynchronus function এর যেখানে আমরা asynch() function use করেছিলাম তাকে catchAsyncErrorsMiddleware দিয়ে নিচের মত মুড়িয়ে দিব,

catchAsyncErrorsMiddleware(async(req,res,next){})

[[FILENAME : ExpressBoilerTemplate/backend/controllers/usersController.js]]
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
const catchAsyncErrorsMiddleware = require("../middleware/catchAsyncErrorsMiddleware");
const ErrorHandler = require("../utils/ErrorHandler");


// Get All Product
exports.getAllUsers = catchAsyncErrorsMiddleware(async(req, res) => {
  res.status(200).json({
    success: true,
    message: "getAllUsers route is working",
  });
})

  1. এবার postman software এ test করব

postman success screenshot

Handling unhadled promise rejection error


unhadled promise rejection error বলতে , কোন কারনে link এ কোণ spelling mistake হয়ে গেলে যাতে server forcedly shut down হয়ে যায় সেই কাজ করা unhadled promise rejection error কে অবশ্যি ExpressBoilerTemplate/backend/server.js file এর সবার নিচে just export করার আগে define করতে হয়

  1. এজন্য ExpressBoilerTemplate/backend/server.js file এ গিয়ে প্রথমে app.listen() কে একটা server নামের varibale এ রাখব, তারপর process.on() method এ unhandledRejection event use করে একটা callback function input দিব যা প্রয়োজনিয় message console করবে, server close করবে, process exit করবে

server.close() method ও একটা callback function recieve করবে যেখানে process.exit() method invoke

[[FILENAME : ExpressBoilerTemplate/backend/server.js]]
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
const app = require("./app");
const dotenv = require("dotenv");
const connectDatabase = require("./config/database");
//config
dotenv.config({ path: "backend/config/config.env" });
// Connecting to database
connectDatabase();
const server = app.listen(process.env.PORT, () => {
  console.log(`Server is working on http://localhost:${process.env.PORT}`);
});
// unHandled promise rejection
process.on("unhandledRejection", (err, promise) => {
  console.log(`Error: ${err.message}`);  
  console.log(`Shutting down the server due to Unhandled Promise Rejection`);
  server.close(() => {
    process.exit(1);
  });
});

  1. এবার terminal এ test করার জন্য আগে কিছু error create করতে হবে তাই ExpressBoilerTemplate/backend/config/database.js file এর .catch() method কে comment out করে দিব যাতে error auto catch হয় এ solve না হয়ে যায় এবং

[[FILENAME : ExpressBoilerTemplate/backend/config/database.js]]
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
const mongoose = require("mongoose");
const connectDatabase = () => {
  mongoose
    .connect(process.env.DB_URI, {
      useNewUrlParser: true,
      useUnifiedTopology: true,
    //   useCreateIndex: true, // this is not supported now
    })
    .then((data) => {
      console.log(`Mongodb connected with server: ${data.connection.host}`);
    })
    /* .catch((err) => {
        console.log(err);
    }); */
};
module.exports = connectDatabase;

  1. এবং ExpressBoilerTemplate/backend/config/config.env file এর DB_URI variable এর value নষট করে দিব দেখব terminal এ error আসবে

[[FILENAME : ExpressBoilerTemplate/backend/config/config.env]]
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
PORT=5000
DB_URI="mongo://localhost:27017/Ecommerce"

postman success screenshot

  1. test success হলে again ExpressBoilerTemplate/backend/config/config.env file এর DB_URI variable এর value ঠিক করে দিব

[[FILENAME : ExpressBoilerTemplate/backend/config/config.env]]
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
PORT=5000
DB_URI="mongodb://localhost:27017/Ecommerce"

Handling uncaught error


uncaught error বলতে , যদি project এ কোণ undefined variable থাকার কারনে যেই error টা দেয় তাকে handle করতে হবে uncaught কে অবশ্যি ExpressBoilerTemplate/backend/server.js file এর সবার উপরে define করতে হয়

  1. এজন্য ExpressBoilerTemplate/backend/server.js file এ গিয়ে একদম শুরুতে process.on() method এ uncaughtException event use করে একটা callback function input দিব যা প্রয়োজনিয় message console করবে, তারপর process exit করবে

server.close() method কে invoke করা লাগবে না

[[FILENAME : ExpressBoilerTemplate/backend/server.js]]
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
const app = require("./app");
const dotenv = require("dotenv");
const connectDatabase = require("./config/database");
// Handling Uncaught Exception
process.on("uncaughtException", (err) => {
  console.log(`Error: ${err.message}`);
  console.log(`Shutting down the server due to Uncaught Exception`);
  process.exit(1);
});
//config
dotenv.config({ path: "backend/config/config.env" });
// Connecting to database
connectDatabase();
const server = app.listen(process.env.PORT, () => {
  console.log(`Server is working on http://localhost:${process.env.PORT}`);
});
// unHandled promise rejection
process.on("unhandledRejection", (err, promise) => {
  console.log(`Error: ${err.message}`);  
  console.log(`Shutting down the server due to Unhandled Promise Rejection`);
  server.close(() => {
    process.exit(1);
  });
});

  1. এবার terminal এ test করার জন্য আগে কিছু error create করতে হবে তাই ExpressBoilerTemplate/backend/server.js file এ কোণ undefined variable কে console করে দেখা যেতে পারে

[[FILENAME : ExpressBoilerTemplate/backend/server.js]]
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
const app = require("./app");
const dotenv = require("dotenv");
const connectDatabase = require("./config/database");
// Handling Uncaught Exception
process.on("uncaughtException", (err) => {
  console.log(`Error: ${err.message}`);
  console.log(`Shutting down the server due to Uncaught Exception`);
  process.exit(1);
});
console.log(testUncaughtError)
//config
dotenv.config({ path: "backend/config/config.env" });
// Connecting to database
connectDatabase();
const server = app.listen(process.env.PORT, () => {
  console.log(`Server is working on http://localhost:${process.env.PORT}`);
});
// unHandled promise rejection
process.on("unhandledRejection", (err, promise) => {
  console.log(`Error: ${err.message}`);  
  console.log(`Shutting down the server due to Unhandled Promise Rejection`);
  server.close(() => {
    process.exit(1);
  });
});

terminal error screenshot

  1. এবং ExpressBoilerTemplate/backend/*server.js file এর *undefined variable কে comment out করে দেই

[[FILENAME : ExpressBoilerTemplate/backend/server.js]]
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
const app = require("./app");
const dotenv = require("dotenv");
const connectDatabase = require("./config/database");
// Handling Uncaught Exception
process.on("uncaughtException", (err) => {
  console.log(`Error: ${err.message}`);
  console.log(`Shutting down the server due to Uncaught Exception`);
  process.exit(1);
});
// console.log(testUncaughtError)
//config
dotenv.config({ path: "backend/config/config.env" });
// Connecting to database
connectDatabase();
const server = app.listen(process.env.PORT, () => {
  console.log(`Server is working on http://localhost:${process.env.PORT}`);
});
// unHandled promise rejection
process.on("unhandledRejection", (err, promise) => {
  console.log(`Error: ${err.message}`);  
  console.log(`Shutting down the server due to Unhandled Promise Rejection`);
  server.close(() => {
    process.exit(1);
  });
});

Handling castError error


castError error বলতে , যদি mongoDB তে GET req করার সময় id এর জায়গায় অন্য কিছু দেইয় অথবা id shortend হয়ে যায় তখন এই error দেয়

  1. এজন্য ExpressBoilerTemplate/backend/middleware/error.js file এ গিয়ে errorMiddlewareerr.stack কে console করে সেখান থেকে err.name এর উপরে condtion apply করে এই error টা handle করব

[[FILENAME : ExpressBoilerTemplate/backend/middleware/error.js file]]
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
const errorMiddleware = (err, req, res, next) => {
    err.statusCode = err.statusCode || 500;
    err.message = err.message || "Internal Server Error";
    // console.log(err.stack);
    // Wrong Mongodb Id error
    if (err.name === "CastError") {
      const message = `Resource not found. Invalid: ${err.path}`;
      err = new ErrorHandler(message, 400);
    }
    res.status(err.statusCode).json({
        success: false,
        message: err.message,
    });
}
module.exports = errorMiddleware;

postman screenshot

Creating Standard Model,Controller,Route with all errorhandlers

Standard Model:

  1. প্রথমে root folder এ validator কে install করে নিব

npm i validator

  1. এবার mongoose & validators কে import করেনিব তারপর তারপর mongoose.schema() method দিয়ে user এর schema বা কংকাল বানাতে হবে যেখানে userSchema object এর সকল key-value এর বৈশিষ্ট define করা থাকবে, এরপর সবার নিচে collection Name, schema name সহ mongoose.model() method এর সাহায্যে model টা বানিয়ে inline exports করে দিব।

মনে রাখতে হবে,

basically এই model গুলোই মূলত mongodb এর collection এর মত কাজ করে আর

collection name অবশ্যই singular form এ দিতে হবে

userSchema এর email.unique = true এর মানে হচ্ছে user এর collection এ একই email এর agianst এ কেবল একজনই এবই কেবল মাত্র সেই ব্যক্তিই থাকবে

userSchema এর email.validate[0] = validator.isEmail এটা হচ্ছে validator library আমাদের justify করে দিচ্ছে যে email টা কি সত্যিই valid কিনা

userSchema এর password.select = false এটা হচ্ছে যদি admin কখনো কোন specific user এর details অথবা সব গুলো users information কে GET করতে চায় তাহলে এই password এর select key false হওয়াতে সে কিছুতেই user এর password কে GET করেতে পারবে না বাকি সব পারবে

userSchema এর avatar এটা হচ্ছে একটা object {} কারন user এর profile pic একটাই থাকে

[[FILENAME: D:\projectsACC\Node-Mongo Advanced Crash Course\ACC_assignment_01\backend\models\usersModel.js]]
"""""""""""""""""""""""""""""""""""""""""""""""""""""""
const mongoose = require("mongoose");
const validator = require("validator");


const userSchema = new mongoose.Schema({
    gender: {
        type: String,
        required: [true, "Please Enter Your Gender"],
        maxLength: [10, "Gender cannot exceed 10 characters"],
        minLength: [4, "Gender should have more than 4 characters"],
    },
    name: {
        type: String,
        required: [true, "Please Enter Your Name"],
        maxLength: [30, "Name cannot exceed 30 characters"],
        minLength: [4, "Name should have more than 4 characters"],
    },
    contact: {
        type: String,
        required: [true, "Please Enter Your 11 digit contact number"],
        minLength: [11, "ontact number should have 11 characters"],
    },
    email: {
        type: String,
        required: [true, "Please Enter Your Email"],
        unique: true,
        validate: [validator.isEmail, "Please Enter a valid Email"],
    },
    password: {
        type: String,
        required: [true, "Please Enter Your Password"],
        minLength: [8, "Password should be greater than 8 characters"],
        select: false,
    },
    photoUrl: {
        type: String,
        required: true,
    },
    role: {
        type: String,
        default: "user",
    },
    createdAt: {
        type: Date,
        default: Date.now,
    },
});


const userModel = mongoose.model("User", userSchema);
module.exports = userModel;

Standard Controller

  1. pagination বা limiting এর জন্য আমরা backend\utils\apiFeatures.js file এ pagination feature এর function বানিয়েছি
[[FILENAME: D:\projectsACC\Node-Mongo Advanced Crash Course\ACC_assignment_01\backend\utils\apiFeatures.js]]
"""""""""""""""""""""""""""""""""""""""""""""""""""""""
class ApiFeatures {
    constructor(query, queryStr) {
        this.query = query;
        this.queryStr = queryStr;
    }


    /* pagination(resultPerPage) {
      const currentPage = Number(this.queryStr.page) || 1;
   
      const skip = resultPerPage * (currentPage - 1);
   
      this.query = this.query.limit(resultPerPage).skip(skip);
   
      return this;
    } */

    pagination(limit) {

        this.query = this.query.limit(limit)

        return this;
    }

}

module.exports = ApiFeatures;

  1. এখানে আমরা সব ধরনের errorhandler,apifeatures দের import করে করে requiremnet অনুযায়ি যাবতিয় সব CRUD operation এর controller function গুলা বানিয়েছি

[[FILENAME: D:\projectsACC\Node-Mongo Advanced Crash Course\ACC_assignment_01\backend\controllers\usersController.js]]
"""""""""""""""""""""""""""""""""""""""""""""""""""""""
const catchAsyncErrorsMiddleware = require("../middleware/catchAsyncErrorsMiddleware");
const userModel = require("../models/usersModel");
const ApiFeatures = require("../utils/apiFeatures");



// create a user - AdminRoute
exports.createUser = catchAsyncErrorsMiddleware(async (req, res, next) => {
    const user = await userModel.create(req.body);
    res.status(201).json({
        success: true,
        user,
    });
})


// Get All users
exports.getAllUsers = catchAsyncErrorsMiddleware(async (req, res, next) => {
    const limit = req.query.limit;
    const usersCount = await userModel.countDocuments();

    const apiFeature = new ApiFeatures(userModel.find(), req.query)
        .pagination(limit);

    const users = await apiFeature.query;

    res.status(200).json({
        success: true,
        message: limit && limit <= usersCount ? `${limit} user is showing out of ${usersCount} users` : `All ${usersCount} users are showing`,
        users,
    });
});


// update a User - AdminRoute
exports.updateUser = catchAsyncErrorsMiddleware(async (req, res, next) => {
    const id = req.params.id;
    const updateInfo = req.body;
    const user = await userModel.findById(id);
    if (!user) {
        return res.status(404).json({
            success: false,
            message: "User not found",
        });
    }
    const updatedUser = await userModel.findByIdAndUpdate(req.params.id, req.body, {
        new: true,
        runValidators: true,
        useFindAndModify: false,
    });
    res.status(200).json({
        success: true,
        message: "User updated successfully",
        updatedUser,
    });
})


// delete a User - AdminRoute
exports.deleteUser = catchAsyncErrorsMiddleware(async (req, res, next) => {
    const id = req.params.id;
    const user = await userModel.findById(id);
    if (!user) {
        return res.status(404).json({
            success: false,
            message: "User not found",
        });
    }

    await user.remove();
    // await productModel.findByIdAndDelete(id); // এটাও চলবে

    res.status(200).json({
        success: true,
        message: "User deleted successfully",
    });
})


// Get User details by ID
exports.getUserDetails = catchAsyncErrorsMiddleware(async (req, res, next) => {
    const id = req.params.id;
    const user = await userModel.findById(id);
    if (!user) {
        return res.status(404).json({
            success: false,
            message: "User not found",
        });
    }
    res.status(200).json({
        success: true,
        message: "getUserDetails route is working",
        user,
    });
})


// Get a random user from the database
exports.getRandomUser = catchAsyncErrorsMiddleware(async (req, res, next) => {
    const users = await userModel.find();
    const randomUser = users[Math.floor(Math.random() * users.length)];
    res.status(200).json({
        success: true,
        message: "getRandomUser route is working",
        randomUser,
    });
})

// update multiple users information based on given id and information through body
exports.updateMultipleUsers = catchAsyncErrorsMiddleware(async (req, res, next) => {
    const users = await userModel.updateMany(
        { _id: { $in: req.body.ids } },
        { $set: { name: req.body.name } }
    );
    res.status(200).json({
        success: true,
        message: "updateMultipleUsers route is working",
        users,
    });
})

Standar Routes

  1. এখানে আমরা সব ধরনের controller functions দের import করে করে requiremnet অনুযায়ি যাবতিয় সব CRUD operation এর controller function গুলার জন্য route বানিয়েছি

[[FILENAME: D:\projectsACC\Node-Mongo Advanced Crash Course\ACC_assignment_01\backend\routes\usersRoutes.js]]
"""""""""""""""""""""""""""""""""""""""""""""""""""""""
const express = require("express");
const { getAllUsers, createUser, updateUser, deleteUser, getUserDetails, getRandomUser, updateMultipleUsers } = require("../controllers/usersController");



const router = express.Router();



router.route("/random/").get(getRandomUser);
router.route("/all").get(getAllUsers);
router.route("/save").post(createUser);
router.route("/update/:id").patch(updateUser);
router.route("/delete/:id").delete(deleteUser);
router.route("/random/:id").get(getUserDetails);
router.route("/bulk-update").patch(updateMultipleUsers);







module.exports = router;

Deploy in MongoDB

Very simple

Mongodb তে নতুন একটা project বানিয়ে database এর ভতরের connect এ click করে তার ভিতরের uri টাকে copy করে নিব

backend\config\config.env এ গিয়ে DB_URI এর value হিসেবে assign করে দিব

just একটা কাজ extra করতে হবে আর তাহল,

uri এর শেষে "/?" এর বদলে /ACC_ASSIGNMENT_01? দিতে হবে

এখানে ACC_ASSIGNMENT_01 হচ্ছে databse collection এর নাম

assacc02's People

Contributors

abuabddullah avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.