Endpoint Routing Basics
π― What You'll Learn
- What routing is and why it matters
- Endpoint routing architecture
- How routing works in ASP.NET Core
- UseRouting and UseEndpoints middleware
- Route matching process
- Endpoint metadata
What is Routing?
Routing is the process of mapping incoming HTTP requests to specific endpoints (controllers, actions, handlers) based on the URL pattern.
URL: /api/products/123
β
Route: /api/products/{id}
β
Controller: ProductsController
Action: GetProduct(int id)
β
Result: Product with ID 123
Routing is like a GPS for your applicationβit determines which code should handle each incoming request based on the URL.
Endpoint Routing Architecture
ASP.NET Core uses endpoint routing, which separates route matching from endpoint execution.
1. UseRouting() β Match the route
β
[Other middleware can run here]
β
2. UseEndpoints() β Execute the endpoint
Why Two Phases?
This separation allows middleware (like authentication, authorization, CORS) to run after route matching but before endpoint execution.
var app = builder.Build();
app.UseRouting(); // 1. Match route
// Middleware that needs route information
app.UseCors();
app.UseAuthentication();
app.UseAuthorization();
app.MapControllers(); // 2. Execute endpoint (implicit UseEndpoints)
Route Matching Process
1. Request arrives: GET /api/products/123
β
2. UseRouting() examines all registered routes
β
3. Finds matching route: /api/products/{id}
β
4. Extracts route values: { id = 123 }
β
5. Sets endpoint metadata
β
6. Middleware runs (auth, CORS, etc.)
β
7. UseEndpoints() executes the endpoint
β
8. ProductsController.GetProduct(123) runs
Configuring Routing
Minimal API Routing
var app = builder.Build();
// Map endpoints directly
app.MapGet("/api/products", () => "All products");
app.MapGet("/api/products/{id}", (int id) => $"Product {id}");
app.MapPost("/api/products", () => "Create product");
app.Run();
Controller-Based Routing
builder.Services.AddControllers();
var app = builder.Build();
app.UseRouting();
app.UseAuthorization();
app.MapControllers(); // Map all controller endpoints
app.Run();
Endpoint Metadata
Endpoints can have metadata that describes their behavior (authorization, CORS, etc.).
app.MapGet("/api/products", () => "Products")
.RequireAuthorization() // Metadata: requires auth
.RequireCors("AllowAll") // Metadata: CORS policy
.WithName("GetProducts") // Metadata: endpoint name
.WithTags("Products"); // Metadata: OpenAPI tag
Route Priority
When multiple routes match, ASP.NET Core uses route priority to select the best match.
Priority Rules
- Literal segments beat parameters:
/products/new>/products/{id} - Constrained parameters beat unconstrained:
{id:int}>{id} - More segments beat fewer:
/api/products/{id}>/api/{controller}
// Priority 1 (highest) - literal segment
app.MapGet("/products/new", () => "New product form");
// Priority 2 - constrained parameter
app.MapGet("/products/{id:int}", (int id) => $"Product {id}");
// Priority 3 (lowest) - unconstrained parameter
app.MapGet("/products/{slug}", (string slug) => $"Product {slug}");
// URL: /products/new β Matches route 1
// URL: /products/123 β Matches route 2
// URL: /products/laptop β Matches route 3
Complete InvenTrack Example
var builder = WebApplication.CreateBuilder(args);
// Add services
builder.Services.AddControllers();
var app = builder.Build();
// Configure middleware pipeline
app.UseHttpsRedirection();
// 1. Match route
app.UseRouting();
// Middleware that needs route information
app.UseCors();
app.UseAuthentication();
app.UseAuthorization();
// 2. Execute endpoint
app.MapControllers();
// Additional endpoints
app.MapGet("/health", () => "Healthy").WithName("HealthCheck");
app.Run();
[ApiController]
[Route("api/[controller]")]
public class ProductsController : ControllerBase
{
// GET /api/products
[HttpGet]
public IActionResult GetProducts()
{
return Ok("All products");
}
// GET /api/products/123
[HttpGet("{id}")]
public IActionResult GetProduct(int id)
{
return Ok($"Product {id}");
}
}
Key Takeaways
- Routing: Maps URLs to endpoints (controllers, actions, handlers)
- Endpoint routing: Two-phase process (match β execute)
- UseRouting(): Matches the route
- MapControllers(): Executes the endpoint (implicit UseEndpoints)
- Separation: Allows middleware to run between matching and execution
- Endpoint metadata: Describes endpoint behavior (auth, CORS, etc.)
- Route priority: Literal > constrained > unconstrained
- Minimal APIs: Use
MapGet,MapPost, etc. - Controllers: Use
MapControllers()
You now understand endpoint routing basics! In the next section, we'll explore Conventional vs Attribute Routingβtwo different ways to define routes in ASP.NET Core.