এই লেকচারটিতে ASP.NET Core-এর Routing মেকানিজমের একটি অত্যন্ত গুরুত্বপূর্ণ বিষয় নিয়ে আলোচনা করা হয়েছে: Route Precedence বা Route Selection Rules। যখন একটি ইনকামিং URL একাধিক Route-এর সাথে ম্যাচ করে, তখন অ্যাপ্লিকেশন কীভাবে সিদ্ধান্ত নেয় যে কোন Endpoint-টি এক্সিকিউট হবে, সেটিই এখানে ব্যাখা করা হয়েছে।
চলো পুরো বিষয়টি ধাপে ধাপে বিস্তারিতভাবে বুঝে নিই।
১. বিস্তারিত বিশ্লেষণ (Comprehensive Breakdown)
ক. মূল প্রশ্ন: একাধিক Route ম্যাচ করলে কোনটি সিলেক্ট হবে? সাধারণত মনে হতে পারে যে, আমরা কোডে যে Route-টি আগে লিখেছি বা রেজিস্টার করেছি, সেটিই আগে এক্সিকিউট হবে। কিন্তু ASP.NET Core-এ ব্যাপারটি এমন নয়। এখানে Order of execution কোডের লাইনের ওপর নির্ভর করে না, বরং কিছু নির্দিষ্ট Precedence Rules (অগ্রাধিকারের নিয়ম) ফলো করে।
খ. Route Selection-এর ৪টি প্রধান নিয়ম (Four Precedence Rules)
- Rule 1: More Segments (অধিক সেগমেন্ট):
যে URL template-এ সেগমেন্টের সংখ্যা বেশি, তার Priority বা ওয়েট সবচেয়ে বেশি।
উদাহরণ:
A/B/C/D(৪টি সেগমেন্ট) সবসময়A/B/C(৩টি সেগমেন্ট)-এর চেয়ে বেশি অগ্রাধিকার পাবে। - Rule 2: Literal Text > Parameter (প্যারামিটারের চেয়ে সাধারণ টেক্সটের ওয়েট বেশি):
যদি কোনো Route-এ সরাসরি নির্দিষ্ট টেক্সট (Literal text) লেখা থাকে, তবে সেটি ডাইনামিক Parameter-এর চেয়ে বেশি অগ্রাধিকার পায়।
উদাহরণ:
A/B(Literal text) এবংA/{parameter}। যদি ইউজারA/Bলিখে রিকোয়েস্ট পাঠায়, তবে এটি দুটি Route-এর সাথেই ম্যাচ করে। কিন্তু Rule 2 অনুযায়ীA/B(Literal text) সিলেক্ট হবে। তবে ইউজার যদিA/Cপাঠায়, তখন এটি প্রথমটির সাথে ম্যাচ করবে না, তাই বাধ্য হয়ে দ্বিতীয়টি (A/{parameter}) সিলেক্ট করবে। - Rule 3: Constraints > No Constraints (কনস্ট্রেইন্টের ওয়েট বেশি):
যদি কোনো Parameter-এ Constraint (যেমন: ডাটা টাইপ রেস্ট্রিকশন) দেওয়া থাকে, তবে সেটি সাধারণ Parameter-এর চেয়ে বেশি স্পেসিফিক হিসেবে গণ্য হয়।
উদাহরণ:
A/{b:int}এবংA/{b}। যদি ইউজারA/10হিট করে, তবে এটি উভয়ের সাথেই ম্যাচ করে। কিন্তু যেহেতু প্রথমটিতেintConstraint আছে, তাই প্রথমটি সিলেক্ট হবে। - Rule 4: Parameter > Catch-all Parameter (ক্যাচ-অলের ওয়েট সবচেয়ে কম): Catch-all Parameter (যেখানে “ বা Asterisk ব্যবহার করা হয়) যেকোনো কিছুর সাথেই ম্যাচ করে যায়। তাই এর Priority সবচেয়ে কম রাখা হয়েছে। একটি সাধারণ Parameter সবসময় Catch-all-এর আগে সুযোগ পাবে।
গ. বাস্তব উদাহরণ (Real-world Scenario & Code Implementation) লেকচারে Sales Report-এর একটি চমৎকার উদাহরণ দেওয়া হয়েছে। চলো কোড দিয়ে বিষয়টি বুঝি:
app.UseEndpoints(endpoints =>
{
// Route 1: Using Parameters (year and month)
endpoints.MapGet("sales-report/{year}/{month}", async context =>
{
var year = context.Request.RouteValues["year"];
var month = context.Request.RouteValues["month"];
await context.Response.WriteAsync($"Showing sales report for Year: {year}, Month: {month}");
});
// Route 2: Using Literal Text (Specific to 2024 and Jan)
endpoints.MapGet("sales-report/2024/jan", async context =>
{
await context.Response.WriteAsync("Showing sales report exclusively for 2024 January!");
});
});
- কী ঘটবে?
ইউজার যদি
sales-report/2024/janURL-এ হিট করে, এটি উপরের দুটি Route-এর সাথেই হুবহু ম্যাচ করে। কিন্তু Rule 2 অনুযায়ী, যেহেতু দ্বিতীয় Route-টিতে2024/janসরাসরি Literal Text হিসেবে আছে, তাই দ্বিতীয়টিই এক্সিকিউট হবে। অন্যদিকে, ইউজার যদিsales-report/2023/janহিট করে, তবে এটি দ্বিতীয়টির সাথে ম্যাচ করবে না, তখন প্রথমটি (Parameter-ভিত্তিক Route) এক্সিকিউট হবে।
ঘ. ডেভেলপারদের জন্য সুবিধা (The Main Benefit) এই মেকানিজমের সবচেয়ে বড় সুবিধা হলো— ডেভেলপারদের Route ডেফিনিশনের অর্ডার নিয়ে চিন্তা করতে হয় না। তুমি চাইলে Literal Text-এর Route-টি কোডের একদম নিচেও লিখতে পারো। ASP.NET Core ইঞ্জিন নিজে থেকেই Precedence Rules অ্যাপ্লাই করে সঠিক Endpoint-টি খুঁজে নেবে।
২. মূল্যায়ন (Critical Evaluation)
-
Strengths (সবল দিক):
-
৪টি নিয়ম খুব সহজ ভাষায় এবং লজিক্যালি ব্রেকডাউন করা হয়েছে।
-
Order of code যে Routing-এ প্রভাব ফেলে না, এই কনসেপ্টটি উদাহরণসহ দারুণভাবে ক্লিয়ার করা হয়েছে।
-
Limitations (সীমাবদ্ধতা):
-
যদি দুটি Route-এর Precedence Weight হুবহু একই হয়ে যায় (Conflict), তখন অ্যাপ্লিকেশনটি যে একটি
AmbiguousMatchExceptionথ্রো করে, তা এই লেকচারে উল্লেখ করা হয়নি।
৩. পরবর্তী ধাপ ও প্রাসঙ্গিক বিষয় (Future Learning Path)
Routing Precedence নিয়ে আরও ডিপ নলেজ অর্জনের জন্য তোমার নিচের Keywords এবং টপিকগুলো নিয়ে স্টাডি করা উচিত:
- AmbiguousMatchException: (যখন রাউটিং ইঞ্জিন সিদ্ধান্ত নিতে পারে না কোন রুটটি সিলেক্ট করবে)।
- Catch-all Parameters (
{*catchall}): (কীভাবে এটি কাজ করে এবং কখন ব্যবহার করতে হয়)। - Route
OrderProperty: (অ্যাডভান্সড সিনারিওতে কীভাবে ম্যানুয়ালি রুটের প্রায়োরিটি ফোর্স করা যায়)। - Endpoint Routing Middleware Pipeline: (ইন্টারনালি
UseRoutingএবংUseEndpointsকীভাবে এই নিয়মগুলো অ্যাপ্লাই করে)।