বাংলা আর্টিকেল:{One-to-Many Prisma & CRUD} Learn MERN Stack By Create Real-Estate Project -Part_5

বাংলা আর্টিকেল:{One-to-Many Prisma & CRUD} Learn MERN Stack By Create Real-Estate Project -Part_5

(One-to-Many Love Prisma & CRUD) ->Create a Real-estate Management Full-Stack Project To Learn React, NodeJs, MongoDB, Prisma And More Web Tools.

সালমান ও রাফিদ দুইজন গভীর বন্ধু। একজন আরেকজনকে ছাড়া চলেই না। সকাল হলে মন্টু কাকার দোকানে আড্ডা দেয়া ,গল্প করা নিত্যদিনের অভ্ভাশ । তবে, আজ্কাল সালমান একটু ডুব মারতেছে। ঘটনা কি দেখতে রাফিদ সালমানকে ফোন দিল ।

সকাল ১১.৩০ বাজে ,সালমান তার বাসায় থাকা দেয়াল ঘড়িতে দেখলো। সে বুজল আড্ডা দেয়ার জন্য ডাকছে ,

রাফিদঃ ওই,বেটা বাসায় বসে কয়দিন ধরে ঝিমাচ্ছিস ক্যান ? মন্টু কাকার চায়ের দোকানে আয়,

কিন্তু সালমান বললো, সে বের হতে পারবে না ,কারণ তার মাথায় প্যাচ লেগে আছে। ভিডিও দেখে প্যাচ ছাড়াতে হবে। সে ,কিছুদিন হয় MERN Stack শিখতেছে।

রাফিদঃ কি প্যাচ লাগছে ,আমায় ক।

সালমানঃ আরে, তুই বুজবি না ,এইডা প্রোগ্রামিং মাম্মা ক্যাচাল আছে ।

রাফিদঃ প্রোগ্রামিং না বুঝি, শুনতে তো পারি , লাগলে রিয়াল লাইফ উদহারণ দিয়া বুঝাই দিবি।

সালমানঃ আমি ক্যামনে বুঝামু তোরে ,আমার নিজের মাথায় তো আন্ধা গিট্টু লাইগা আছে। শিখতেছি প্রজেক্ট ক্যামনে বানায়, এর মধ্যে চলে আসছে, কি এক নাম One-to-Many রিলেশনশিপ।

রাফিদঃ ধুর ,বেটা এইডা বুজলি না ? নাম শুইনাই তো বোঝা যাইতেছে । দ্বারা তোরে আমি ,তোর নিজের এক্সাম্পল দিয়েই বুঝাই দিতাছি।

রাফিদ প্রোগ্রামিং জানে না, কিন্তু সে রিয়েল লাইফ এর সাথে রিলেট করতে পারে ভালো।

সালমানঃ কেমনে ? কি বুজলি,আমায় বুঝা !!

রাফিদঃ তোর ফ্যামিলিতে মোট সদস্য সংখ্যা ৫ জন। তোরা ৪ ভাইবোন আর তোর বাবা ১। এখানে খেয়াল করলে দেখবি তোর বাবা হচ্ছে, তোদের কমন লিংক মানে "One", আর তোরা ৪ ভাই বোন হচ্ছিস তোর বাবার "Many" ।

সালমানঃ তার মানে, আমি হইতাছি "One" আর ওরা সবাই "Many" ?

রাফিদঃ সাব্বাস বেটা ,এইতো বুইঝা গেছো। তুই হচ্ছিস কমন লিংক। আর তোর বাবা মানে আঙ্কেল কে এসোসিয়েট করে, তোরা সবাই গুরুপাক খাচ্ছিস।

সালমানঃ বুজতে পারছি ,তার মানে যদি ডাটাবেস মডেল হিসেবে ধরি তাইলে , User হচ্ছে কমন লিংক আর Post হচ্ছে ওই ছেলে / মেয়ে গুলা।

User পোস্ট নাও করতে পারে, আবার অনেক গুলাও পোস্ট থাকতে পারে ,কিন্তু এসোসিয়েট হবে User এর সাথে ।

রাফিদঃ কি বলিস এসব ,কিসের পোস্ট ?

সালমানঃ কিছু না ,বাট ধন্যবাদ তোরে , গিট্টু খুলছে।

Note: "One-to-many relations" describe a connection between two sets of data where a single item from one set can be linked to several items in the other set. For instance, imagine Users and Posts. One user can have multiple posts associated with them.

Hey Script_Slingers,

সবাই আশাকরি ভালো আছ এবং আগের চ্যাপ্টার এর প্রাকটিস গুলো খুব ভালোভাবে করেছো।

আজকে আমরা Learn MERN Stack By Create Real-Estate Project এর Part_5 কমপ্লিট করতে যাচ্ছি।

পূর্বের আর্টিকেল গুলো থেকে তোমাদের কাছে prisma ও crud এর সম্পূর্ণ একটা পিকচার মাথার ক্যানভাসে আঁকা হয়ে গেছে আশাকরি।

তার ধারাবাহিকতায় আজকে আমরা One-to-many relationshisp নিয়ে আলোচনা করব। একটা ছোট্ট crud oparetion করব। একটা প্রাকটিক্যাল প্র্যাক্টিস আরকি।

lets start with me.

#One_To_Many_Relationship:

অলরেডি তুমি জান One-to-one রিলেশনশিপ কিভাবে কাজ করে।

prisma model বা schima তে যে রিলেসন এ হোকনা কেন, সব গুলোই একই attribute ব্যবহার করে কাজ করে। শুধু ডিফারেন্স হয় কি কি প্রসেস এ ফিল্ড গুলো একে অন্যের সাথে সম্পর্ক তৈরী করে এবং ডাটা স্টোর করার ধরণ।

যেমন ধরো ,আমরা ওয়ান to ওয়ান রিলেসন এ, এটা প্রমান করার চেষ্টা করেছি ,একজন user এর জন্য একটাই profile থাকবে এবং একটা profile এর জন্য একজনই user থাকবে।

কিন্তু one-to-many রিলেশনশিপ এ ,তুমি যদি আর্টিকেল এর শুরুতে দেয়া পিতাপুত্রের উদহারণ লক্ষ্য কর, দেখবা , একজন পিতার অনেক গুলো সন্তান থাকতে পারে, আবার কোনো সন্তান নাও থাকতে পারে ।সন্তান থাকুক বা না থাকুক তাদের কমন লিংক হবে পিতা।

প্রত্যেক টি সন্তান এর আবার আলাদা আলাদা নাম হতে পারে ,কিন্তু এখানে মূল বিষয় হচ্ছে পিতা তার সন্তানদের কিভাবে তারবাসায় রাখবে।

Note: বাসায় রাখা মানে, ফিল্ড এর মধ্যে রাখা ।

যখন কোন সন্তান থাকবে না তখন চিলড্রেন ফিল্ড থাকবে একটা empty array । অন্যদিকে যদি চিলড্রেন থাকে তবে তা array এর মধ্যে array of অবজেক্ট আকারে থাকবে।

চল ,আমরা user আর post এক্সাম্পল এর মাধ্যমে দেখি ,

প্রত্যেক user এবং user(father) এর কিছু posts(children) থাকবে। প্রত্যেকটি post এর আলাদা আলাদা title ,id, author থাকতে পারে যা, post মডেল এ আমরা বলে দিতে পারি।

কিন্তু, user তার posts গুলোকে User মডেল বা কালেকশন এ posts(house) নামে ফিল্ড ডিক্লার করে array আকারে রাখবে। এবং post মডেল এর সাথে user মডেল রিলেসন ঘটাবে, user এর email এর উপর ডিপেন্ড করে।

//prisma/schema.prisma
model User {
  id      String   @id @default(auto()) @map("_id") @db.ObjectId
  email   String   @unique
  profile Profile?
  posts   Post[]
}

model Profile {
  id        String @id @default(auto()) @map("_id") @db.ObjectId
  name      String
  user      User   @relation(fields: [userEmail], references: [email])
  userEmail String @unique
}

model Post {
  id          String @id @default(auto()) @map("_id") @db.ObjectId
  title       String
  authorEmail String 
  author      User   @relation(fields: [authorEmail], references: [email])
}

Note : আমরা একই স্কিমা বা ডাটাবেস এ অনেক টাইপ এর রিলেশনশিপ মেইনটেইন করতে পারি।

খেয়াল করলে দেখবা , posts field রিপ্রেসেন্ট করে one-to-many relationship যা , Post model, এর মধ্যে বলে দিচ্ছে author হবে User এবং User মডেল এর সাথে Post মডেল এর সম্পর্ক হবে authorEmail এর মাধ্যমে। এই authorEmail রিপ্রেসেন্ট করে User এর email ।

মূলত authorEmail হচ্ছে এখানে কানেকশন ব্রিজ এবং posts[ ] ফিল্ড হচ্ছে ব্রিজ থেকে আসা সবগুল ডাটার স্টোরেজ।

Note :সাধারণত সবাই id use করে ,তবে আমরা ইমেইল দিয়ে করছি। কারণ User ইমেইল হচ্ছে আমাদের ডাটাবেস এ ইউসার এর ইডেন্টিফায়ার ইউনিক। এবং User মডেল এ প্রত্যেক user এর করা পোস্ট গুলো থাকবে array আকারে posts ফিল্ড এর মধ্যে ।

তুমি নিচের ডায়াগ্রাম দেখলে আরো ক্লিয়ার বুজতে পারবা :

এবং Posts ফিল্ড এর আউটপুট আসবে :

//posts OUTPUT
[
    {
      "id": "64f132d46a5bc1f5030bceb3",
      "title": "2nd New Title",
      "authorEmail": "2@gmail.com"
    },
    {
      "id": "64f132f16a5bc1f5030bceb4",
      "title": "Ai CHange The World",
      "authorEmail": "2@gmail.com"
    }
]

আশাকরি বুজতে পারছ ।

কনসেপ্ট বুজে গেলে কোড করা সহজ। আমরা এখন আমাদের মডেল অনুযায়ী একটা crud করব।

কিন্তু তার আগে , আমাদের prisma স্কিমা তে যেহেতু চেঞ্জ আসছে ,তাই আমরা ডাটাবেস কে জানাই দিতে চাই ।

তোমার সার্ভার ফোল্ডার এর টার্মিনালে কমান্ড করতে হবে :

//terminal. prisma-crud/server$ 
npx prisma db push

টার্মিনাল আউটপুট রিটার্ন করবে :

//terminal Output
Environment variables loaded from .env
Prisma schema loaded from prisma/schema.prisma
Datasource "db": MongoDB database "prisma-crud" at "cluster0.7rttrttluw.mongodb.net"
Applying the following changes:

[+] Collection `User`
[+] Collection `Profile`
[+] Collection `Post`
[+] Unique index `User_email_key` on ({"email":1})
[+] Unique index `Profile_userEmail_key` on ({"userEmail":1})


🚀  Your database indexes are now in sync with your Prisma schema. Done in 11.47s

✔ Generated Prisma Client (v5.2.0) to ./node_modules/@prisma/client in 115ms

Datasource "db": MongoDB database "prismaCrud" at "cluster0.utols.mongodb.net" এখানে তোমার ডাটাবেস নাম এবং ক্লাস্টার ডিটেলস শো করবে।

এখন তুমি টার্মিনাল এ npm start কমান্ড চালাতে পার। যা আমাদের এপ্লিকেশন সার্ভ করবে।


let's do the crud

#One_to_many_CRUD:

তোমার কাছে নিশ্চই আগের অর্গানাইজ করা ফোল্ডার এবং ফাইল আছে। আমরা সেখানে কোড করব।

টেক্সট এডিটর এ সার্ভার ফোল্ডার ওপেন করে ,controllers ফোল্ডার এর মধ্যে userController.js ফাইল চলে যাও :

#controllers/userController.js:

আমরা createUser ফাঙ্কশন এ কিছু চেঞ্জ আনব। এখন যেহেতু আমাদের Post মডেল আছে তাই ,যখন user তৈরী করতে যাব , আমাদের ডাটাবেস এ ইনিশিয়াল ভাবে পোস্ট এর জন্য একটা ফিল্ড ইনক্লুড করে দিতে হবে । যেমন ভাবে ইউসার create করার সময় Profile বলে দিয়েছিলাম:

#createUser Function :

নিচের কোডে খেয়াল করলে দেখবে :

//controllers/userController.js
//rest of the code ...

// Create a new user and profile
const createUser = async (req, res) => {
  try {
    const { email, profile, posts } = req.body;

    const existingUser = await prisma.user.findUnique({
      where: { email: email },
    });

    if (!existingUser) {
      const createUser = await prisma.user.create({
        data: {
          email: email,
          profile: {
            create: profile,
          },
          posts: {
            create: [posts],
          },
        },
        include: {
          profile: true,
          posts: true,
        },
      });

      res.json({
        message: "User Sucess Fully Created",
        user: createUser,
      });
      return;
    }

    res.json({
      message: "You Are Already In Database",
      user: existingUser,
    });
  } catch (error) {
    console.error(error);
    res.status(500).json({ error: "Failed to create user." });
  }
};

Note: তুমি পুরো কোড নিজের হাতে লিখলে বুজতে সহজ হবে।

  1. Input Data:
  • প্রথমেই ,আমরা ক্লায়েন্ট / user এর থেকে input data হিসেবে HTTP request(req.body) এর মধ্যে এক্সপেক্ট করছি user এর email, profile,এবং posts। যা ডিস্ট্রাক্চার করে নিয়ে নিয়েছি const { email, profile, posts } = req.body
  1. Check for Existing User:

    • এরপর existingUser ভ্যারিয়েবল এর মধ্যে prisma কোয়েরি user.findUnique method এর where: { email: email } ক্লোস ব্যবহার করে, প্রথমেই চেক করে নিয়েছি ডাটাবেস থাকা email ও ক্লায়েন্ট এর দেয়া email ম্যাচ করে কিনা!।

    • যদি email ম্যাচ না করে থাকে, তার মানে সে আমার ডাটাবেস এ এক্সিস্টিং ইউসার না।

    • সুতরাং, আমাদের তার জন্য একটা নতুন user তৈরী করতে হবে। তাই (if (!existingUser)) কন্ডিশন চেক করেছি।

  2. const createUser = await prisma.user.create({ ... });:

    • এই লাইন মূলত prisma create কোয়েরি ব্যবহার করছে। আমরা prisma.user.create ফাঙ্কশন বলে দেয়ার মাধ্যমে user collection এর মধ্যে user কে রেজিস্টার করছি বা নতুন user তৈরী করছি।
  3. data: { ... }:

    • prisma তে data হচ্ছে মূল object, যেখানে তুমি, specify করে দিবে user তৈরির জন্য কি কি data আমাদের দরকার।
  4. email: email:

    • আমরা মডেল ডিক্লের করার সময় বলেদিয়েছি user এর মাস্ট একটা email থাকতে হবে । যা req.body থেকে আমরা পাই এবং data অবজেক্ট এর মধ্যে email এর জায়গায় ক্লায়েন্ট এর দেয়া ইমেইলরেখে দিয়েছি।
  5. profile: { create: profile }:

    • এটি user এর জন্য নতুন profile তৈরী করে যা user এর সাথে এসোসিয়েট হবে ,মডেল অনুযায়ী। আমরা req.body থেকে profile অবজেক্ট এর মাধ্যমে ডাটাগুলো পাব এবং data অবজেক্ট এ রাখব। create keyword ব্যবহার হয় specify করে new profile should be created । যদি ক্লায়েন্ট profile অবজেক্ট না provide করে তবে null থাকবে।
  6. posts: { create: [posts] }:

    • এটি একইভাবে post create করে । create keyword ব্যবহার করে , এবং আমাদের মডেল অনুযায়ী এটা একটা array of posts এক্সপেক্ট করে ,যা posts data তৈরী করবে according to posts অবজেক্ট from req.body । ক্লায়েন্ট যদি posts ডাটা provide না করে তবে জেনারেলই একটা empty array হবে।
  7. include: { ... }:

    • include section specifies করে কি কি ডাটা আমরা user তৈরির সময় নিচ্ছি। ক্লায়েন্ট চাইলে ডাটা দিতে পারে, আবার নাও দিতে পারে। না দিলে null বা এম্পটি array হবে।

    • profile: true indicates that the user's profile should be included.

    • posts: true indicates that the user's posts should be included.

  8. Sending a JSON Response:

    • ডাটা include করার পরে ক্লায়েন্ট এর কাছে একটা রেসপন্স চলে যাবে ।

    • The response back a success message: "User Successfully Created".

    • It also responds back a details about the newly created user: user: createUser.

  9. return:

    • আমাদের user তৈরী হওয়ার পরে if এস্টেটমেন্ট কে return করে দিব। রিটার্ন এস্টেটমেন্ট ব্যবহার করে।

Note : যেহেতু else ব্লক বলি নি ,তাই আমাদের রিটার্ন করতে হয়েছে।

  1. res.json({ message: "You Are Already In Database", user: existingUser, }):
  • আর যদি ডাটাবেস এ existing ইমেইল খুঁজে পায় তবে message: "You Are Already In Database" মেসেজ শো করবে।

আউটপুট :

//apiTest.http
###Post Request For Create User 

POST http://localhost:3000/api/users
Content-Type:application/json

{
    "email":"56dev@gmail.com"
}
//OUTPUT WITHOUT POSTS AND PROFILE
{
  "message": "User Sucess Fully Created",
  "user": {
    "id": "64f2932e7d48d8e032bf90b2",
    "email": "56dev@gmail.com",
    "profile": null,
    "posts": []
  }
}

POST http://localhost:3000/api/users
Content-Type:application/json

{
    "email":"56jishan@gmail.com",
    "profile":{
        "name":"Jishan Tanvir"
    },
    "posts":{
        "title":"this is my first Blog Post!"
    }
}
//OUTPUT WITH PROFILE DATA AND POSTS DATA

{
  "message": "User Sucess Fully Created",
  "user": {
    "id": "64f2a8d27d48d8e032bf90b3",
    "email": "56jishan@gmail.com",
    "profile": {
      "id": "64f2a8d37d48d8e032bf90b4",
      "name": "Jishan Tanvir",
      "userEmail": "56jishan@gmail.com"
    },
    "posts": [
      {
        "id": "64f2a8d37d48d8e032bf90b5",
        "title": "this is my first Blog Post!",
        "authorEmail": "56jishan@gmail.com"
      }
    ]
  }
}

খেয়াল করলে দেখবা posts একটা array এর মধ্যে, posts অবজেক্ট আকারে রেখেদিছে, যার মধ্যে post এর ডিটেলস আছে।

আমরা যখন ইন্ডিভিজুয়াল post তৈরী করব তখন , authorEmail এর উপর ভিত্তি করে আলাদা আলাদা id ও টাইটেল মেনশন করে নতুন অবজেক্ট array তে include করব।


#getUserData_Function :

আমাদের user এর ডাটা গেট করায় কোন চেঞ্জ নাই। তুমি postman বা অন্য যেকোন, ক্লায়েন্ট থেকে রিকোয়েস্ট করলে দেখবে ডাটাবেস এ থাকা সবগুল ডাটা শো করছে।

আউটপুট :

//apiTest.http
GET http://localhost:3000/api/users
//OUTPUT FOR ALL USER DATA IN DATABES
[
  {
    "id": "64eeb25031ee19a64f558000",
    "email": "dev@gmail.com",
    "profile": null,
    "posts": []
  },
  {
    "id": "64eeb26831ee19a64f558001",
    "email": "1dev@gmail.com",
    "profile": null,
    "posts": []
  },
  {
    "id": "64f2932e7d48d8e032bf90b2",
    "email": "56dev@gmail.com",
    "profile": null,
    "posts": []
  },
  {
    "id": "64f2a8d27d48d8e032bf90b3",
    "email": "56jishan@gmail.com",
    "profile": {
      "id": "64f2a8d37d48d8e032bf90b4",
      "name": "Jishan Tanvir",
      "userEmail": "56jishan@gmail.com"
    },
    "posts": [
      {
        "id": "64f2a8d37d48d8e032bf90b5",
        "title": "this is my first Blog Post!",
        "authorEmail": "56jishan@gmail.com"
      }
    ]
  }
]

#deleteUser_Function :

ডিলিট করার সময় আমাদের মাথায় রাখতে হবে ,যখন আমরা একজনuser কে ডিলিট করে দিব, তার সাথে এসোসিয়েট থাকা profile এবং posts এগুলো সব ডাটাবেস থেকে ডিলিট করেদিতে হবে। user না থাকলে সঙ্গত কারণে তার ডাটাও থাকার দরকার নেই।

Note : এমনিতে প্রফেশনাল এপ্লিকেশন এ user কে হার্ড ও সফ্ট ডিলিট এর অপসন দিতে হয় ! বাট আমরা এখন ঐদিকে যাবো না।

আমরা প্রথমে চেক করে নিব, ক্লায়েন্ট যে email পেরামস এ দিয়েছে ,সেটা user কালেকশন বা ডাটাবেস এ আছে কিনা ?যদি থাকে ,তাহলে নেক্সট প্রসেস এ আগাতে দিবো নাহয় একটা erroe মেসেজ "User Not Found." দিয়ে ক্লায়েন্ট কে রিপোর্ট করব যে, কোনো প্রসেস fail হইসে।

prisma আমাদের transaction (prisma.$transaction) নামে একটা ফাঙ্কশন provide করে। যার কাজ হচ্ছে group multiple delete operations চালান । যদি একটাও operations fail হয় ,তবে roll back করবে ।

মানে কোন ডাটাই ডিলিট হবে না । এটা ensure করে , সম্পূর্ণ এসোসিয়েট ডাটা ডিলিট হয়েছে অথবা একটাও ডিলিট হয় নাই।

আসো ,এবারে কোড দেখা যাক :

//controllers/userController.js
//rest of the code ...

// Delete a user
const deleteUser = async (req, res) => {
  try {
    const { userEmail } = req.params;

    const findUser = await prisma.user.findUnique({
      where: {
        email: userEmail,
      },
    });

    if (!findUser) {
      res.json({
        message: "User Not FOund",
      });
      return;
    }

    await prisma.$transaction(async (prismaClient) => {
      await prismaClient.profile.deleteMany({
        where: { userEmail: userEmail },
      });
      await prismaClient.post.deleteMany({
        where: { authorEmail: userEmail },
      });
      await prismaClient.user.deleteMany({
        where: { email: userEmail },
      });
    });

    res.json({
      message: "User deleted & Associated Profile and Posts Deleted.",
    });
  } catch (error) {
    console.error(error);
    res.status(500).json({ error: "Failed to delete user." });
  }
};
  1. request parameters থেকে user এর ইমেইল ডিসট্রাক্টর করে নিয়ে আসছি (const { userEmail } = req.params;).

  2. Then, আমরা চেক করছি ডাটাবেস এ থাকা email আর userEmail এক কিনা, await prisma.user.findUnique(...) । যদি এক না হয় তার মানে, ইউসার exist করে না,রেসপন্স ব্যাক করে দিব message সহ ,"User Not Found" এবং stops the process ।

  3. আর যদি ইউসার থাকে , তবে সামনে আগাবো । transaction (prisma.$transaction) ফাঙ্কশন যা একটা কলব্যাক নিবে পেরামিটার হিসেবে ,এবং যার কাজ ,ensure করা either all data ডিলেট হয়েছে or হয়নাই ।

  4. transaction ফাঙ্কশন এর মধ্যে ,তিনটা কাজ হবে for delete operations:

    • Deletes the user's profile data where the user's email matches.

    • Deletes any posts authored by the user based on their email.

    • Finally, it deletes the user's account itself based on their email.

  5. After successfully deleting all this data, it responds with a message saying "User deleted & Associated Profile and Posts Deleted" .


#updateUserData:

আমরা actually ইউসার কে কিছু আপডেট করতে দিবো না এইমুহূর্তে । কারণ আমরা ইউসার থেকে শুধুমাত্র ইমেইল নিচ্ছি।

Note: আপডেট করব তখন যখন , Post ,Profile এসব কালেকশন এ user কোন আপডেট আনতে চাইবে বা নতুন পোস্ট create করতে চাইবে । যা পরবর্তি এপিসোড এ আসবে।


#Consultation:

তুমি এই চ্যাপ্টার থেকে বুঝেগেছো কিভাবে হোল ডাটাবেস রিলেশনশিপ কাজ করে। আমরা চাইলে আমাদের ডাটাবেস এ একাধিক রিলেসন মেইনটেইন করতে পারি। একটা ফুল প্রজেক্ট এর ব্যাকএন্ড নানা ভাবে সাজাতে পারি।

প্রত্যেক ব্যাকএন্ড বা ফ্রন্টএন্ড এর আলাদা আলাদা লজিক আছে তবে অপারেশন গুলো একই। আমরা খুব শিগ্রই আমাদের মেইন প্রজেক্ট এ চলে যাবো। তবে এই রিলেশনশিপ ,ডাটাবেস মেনেজকরা এবং crud এপ্লিকেশন নিয়ে কাজ করা তোমায় সলিড ব্যাকএন্ড বিগ পিকচার নলেজ স্টাব্লিস্ট করবে।

পরবর্তী চ্যাপ্টার এ আমরা , posts ও profile এর crud করব। জানব কিভাবে গ্লোবালি মিডলওয়ার ব্যবহার করে কাস্টম error মেসেজ ক্লায়েন্ট এর জন্য তৈরী করতে হয়।

Follow Me: If you found this explanation helpful and want to learn more about programming, databases, or any other topic, feel free to follow me for more insights and assistance on your journey of knowledge and exploration. Your support is greatly appreciated!

#devTj #tanvir_mehedi #Prisma #mernstack #javascript