আগের পর্বে middleware-এর ধারণাটা এসেছে। আজ সেটাকে আরেকটু গভীরে দেখি, কারণ interview-তে 'middleware কীভাবে কাজ করে' প্রশ্নটা প্রায় নিশ্চিত। একটা request server-এ ঢোকার পর থেকে response যাওয়া পর্যন্ত যা যা ঘটে, তার প্রায় সবই middleware-এর হাতে।
Express-এ middleware তিন রকমের হয়। Built-in - যেমন express.json(), যেটা না থাকলে req.body সবসময় undefined আসবে। Third-party - যেমন cors বা morgan। আর custom - যেটা আপনি নিজে লিখবেন, যেমন auth check বা role check।
Middleware থেকে controller-এ data পাঠানো
একটা সুন্দর pattern হলো: auth middleware token থেকে user বের করে req.user-এ রেখে দেয়, তারপর controller সেই user ব্যবহার করে। এতে প্রতিটা controller-এ বারবার token decode করার দরকার পড়ে না।
function requireAuth(req, res, next) {
const token = req.headers.authorization?.split(" ")[1];
if (!token) return res.status(401).json({ success: false, message: "Login required" });
const payload = verifyToken(token); // { id, role }
req.user = payload;
next();
}
// শুধু এই route-এই auth লাগবে
router.get("/profile", requireAuth, profileController);
router.post("/orders", requireAuth, requireRole("user"), createOrder);লক্ষ্য করুন - middleware route level-এও বসানো যায়। সব route-এ auth লাগে না; যেখানে লাগে শুধু সেখানেই বসান। আরেকটা ব্যাপার: একটা middleware চাইলে chain এখানেই থামিয়ে দিতে পারে - যেমন login না থাকলে 401 পাঠিয়ে দেওয়া। Response পাঠিয়ে দিলে next() ডাকার দরকার নেই, বরং ডাকলেই ভুল হবে।
Async middleware-এর ফাঁদ
Middleware যদি async হয় আর ভেতরে error হয়, Express নিজে থেকে সেটা ধরতে পারে না (Express 4-এ)। হয় try/catch দিয়ে next(err) পাঠাতে হবে, নয়তো একটা ছোট wrapper ব্যবহার করতে হবে। এই একটা লাইনের wrapper পুরো project-এর সব controller-কে নিরাপদ করে দেয়।
const asyncHandler = (fn) => (req, res, next) => {
Promise.resolve(fn(req, res, next)).catch(next);
};
// ব্যবহার
router.get("/users", asyncHandler(async (req, res) => {
const users = await userService.getAll();
res.json({ success: true, data: users });
}));সবাই যে ভুলটা করে
সবচেয়ে চোখে পড়া ভুল: express.json() routes-এর পরে বসানো। তখন সব POST request-এ req.body undefined আসে, আর developer ঘণ্টার পর ঘণ্টা খুঁজে বেড়ায় কোথায় ভুল। Body parser সবসময় routes-এর আগে।
আজকের Practice
আপনার project-এ requireAuth middleware লিখুন (আপাতত token শুধু header-এ আছে কিনা check করুন, আসল JWT পরের পর্বগুলোতে আসবে)। একটা protected route বানিয়ে Postman বা curl দিয়ে token ছাড়া আর token দিয়ে - দুইভাবেই test করুন।
Interview-এ কীভাবে বলবেন
Middleware হলো request pipeline-এর ধাপ - প্রতিটা ধাপ হয় next() ডেকে এগিয়ে দেয়, নয়তো response পাঠিয়ে chain থামিয়ে দেয়। আমি auth-এর মতো cross-cutting কাজ middleware-এ রাখি, আর token থেকে পাওয়া user তথ্য req.user-এ রেখে controller-দের কাজ হালকা রাখি।