
ASP.NET Core-এ Middleware-গুলো একটির পর একটি সারিবদ্ধভাবে সাজানো থাকে, যাকে আমরা Pipeline বলি। যখন ব্রাউজার থেকে কোনো Request আসে, তখন সেটি প্রথম Middleware-এ প্রবেশ করে। প্রথম Middleware তার কাজ শেষ করে চাইলে পরবর্তী Middleware-এর কাছে Request-টি পাঠিয়ে দিতে পারে। এই প্রক্রিয়াটিকেই বলা হয় Middleware Chaining।

মূল বৈশিষ্ট্য:
- Sequential Execution: Middleware গুলো যে ক্রমানুসারে (Order) রেজিস্টার করা হয়, ঠিক সেই ক্রমেই এক্সিকিউট হয়।
- Two-way Journey: Request একবার Pipeline-এর ভেতর দিয়ে শেষ পর্যন্ত যায় (Incoming path), আবার শেষ থেকে শুরুর দিকে ফিরে আসে (Outgoing path)।
২. app.Use বনাম app.Run
Middleware তৈরি করার জন্য আমরা প্রধানত দুটি মেথড ব্যবহার করি:
| ফিচার | app.Use | app.Run |
|---|---|---|
| Purpose | Chaining করার জন্য ব্যবহৃত হয়। | Pipeline শেষ বা Terminate করার জন্য ব্যবহৃত হয়। |
| Parameters | দুটি প্যারামিটার নেয়: HttpContext এবং next (RequestDelegate)। | একটি প্যারামিটার নেয়: HttpContext। |
| Next Call | চাইলে পরবর্তী Middleware-কে কল করতে পারে। | পরবর্তী কোনো Middleware-কে কল করতে পারে না। |
৩. Middleware Chaining ইমপ্লিমেন্টেশন (C# Code)
ধরা যাক, আমরা তিনটি Middleware ব্যবহার করব। প্রথম দুটি হবে app.Use এবং শেষেরটি হবে app.Run (যাকে Terminal Middleware বলা হয়)।
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
// Middleware 1
app.Use(async (context, next) =>
{
await context.Response.WriteAsync("Hello from Middleware 1\n");
// পরবর্তী Middleware-কে কল করা হচ্ছে
await next(context);
// Middleware 2 থেকে ফেরার পর নিচের লাইনটি কাজ করবে
await context.Response.WriteAsync("Back in Middleware 1\n");
});
// Middleware 2
app.Use(async (context, next) =>
{
await context.Response.WriteAsync("Hello from Middleware 2\n");
// পরবর্তী Middleware-কে কল করা হচ্ছে
await next(context);
});
// Middleware 3 (Terminal Middleware)
app.Run(async (context) =>
{
await context.Response.WriteAsync("Hello from Middleware 3 (The End)\n");
});
app.Run();
কোড বিশ্লেষণ:
next(context): এটি একটি Delegate যা পরবর্তী Middleware-কে নির্দেশ করে। এটি কল করলে কন্ট্রোল পরের ধাপে চলে যায়।- Context Passing: লক্ষ্য করুন,
nextমেথড কল করার সময় আমাদেরcontextপাস করতে হচ্ছে। কারণ পরবর্তী Middleware-এর কাজ করার জন্য এই HTTP Context-টি প্রয়োজন।
৪. Short-circuiting কি এবং কেন প্রয়োজন?
সব সময় যে আমাদের পরবর্তী Middleware-কে কল করতে হবে, এমন কোনো বাধ্যবাধকতা নেই। যদি কোনো Middleware সিদ্ধান্ত নেয় যে সে আর রিকোয়েস্ট সামনে পাঠাবে না, তবে তাকে Short-circuiting বলা হয়।
উদাহরণ: ধরুন আপনি একটি Static File (যেমন: image.jpg) রিকোয়েস্ট করেছেন। যদি StaticFileMiddleware ফাইলটি খুঁজে পায়, তবে সে ফাইলটি রিটার্ন করে দেবে এবং পরবর্তী Authorization বা Routing Middleware-এ আর রিকোয়েস্ট পাঠাবে না।
Conditional Chaining-এর উদাহরণ:
app.Use(async (context, next) =>
{
if (context.Request.Query.ContainsKey("stop"))
{
await context.Response.WriteAsync("Terminated early!");
}
else
{
await next(context);
}
});
৫. ডিব্যাগিং ও এক্সিকিউশন অর্ডার
যখন আপনি কোডটি রান করবেন, তখন ব্রাউজারে আউটপুট নিচের মতো দেখাবে:
- Hello from Middleware 1
- Hello from Middleware 2
- Hello from Middleware 3 (The End)
- Back in Middleware 1
গুরুত্বপূর্ণ নোট: ট্রান্সক্রিপ্টে উল্লেখ করা হয়েছে যে ব্রাউজার থেকে রিকোয়েস্ট দিলে অনেক সময় ডাবল ব্রেকপয়েন্ট হিট করে। এটি হয় কারণ আধুনিক ব্রাউজারগুলো স্বয়ংক্রিয়ভাবে /favicon.ico ফাইলের জন্য একটি আলাদা রিকোয়েস্ট পাঠায়। এটি নিয়ে চিন্তিত হওয়ার কিছু নেই।
৬. Best Practices ও সাধারণ ভুল
✅ Best Practices:
- Single Responsibility: প্রতিটি Middleware-কে ছোট রাখুন এবং একটি নির্দিষ্ট কাজ (যেমন: Logging, Authentication, Compression) করতে দিন।
- Correct Ordering: Middleware-এর ক্রম অত্যন্ত গুরুত্বপূর্ণ। যেমন:
Authenticationঅবশ্যইAuthorization-এর আগে থাকতে হবে। - Exception Handling: সাধারণত
ExceptionHandlingMiddlewareসবার আগে রাখা হয় যাতে পরবর্তী যেকোনো স্টেপে এরর হলে তা ধরা যায়।
❌ Common Pitfalls:
- Forgetting
await next(context): যদি আপনি ভুলবশতnextকল না করেন, তবে আপনার অ্যাপ্লিকেশন সেখানেই থেমে যাবে এবং ইউজার হয়তো ব্ল্যাংক স্ক্রিন দেখবে। - Writing to Response after
next:nextকল করার পর Response-এ কিছু লিখলে সাবধান থাকতে হবে, কারণ ততক্ষণে হয়তো Response ব্রাউজারে পাঠানো শুরু হয়ে গেছে।
পরবর্তী পদক্ষেপ:
যখন আপনার Middleware কোড অনেক বড় হয়ে যায়, তখন সব কোড Program.cs-এ রাখা ঠিক নয়। আমরা পরবর্তী লেসনে শিখব কীভাবে একটি Custom Middleware Class তৈরি করে কোডকে আরও পরিচ্ছন্ন করা যায়।