Section 1 of 6

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.

Routing Example Text
URL: /api/products/123
     ↓
Route: /api/products/{id}
     ↓
Controller: ProductsController
Action: GetProduct(int id)
     ↓
Result: Product with ID 123
πŸ’‘ Key Concept

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.

Two-Phase Process Text
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.

Program.cs C#
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

Matching Steps Text
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

Program.cs - Minimal APIs C#
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

Program.cs - Controllers C#
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.).

Endpoint Metadata C#
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

  1. Literal segments beat parameters: /products/new > /products/{id}
  2. Constrained parameters beat unconstrained: {id:int} > {id}
  3. More segments beat fewer: /api/products/{id} > /api/{controller}
Route Priority Example C#
// 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

Program.cs C#
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();
Controllers/ProductsController.cs C#
[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()
🎯 Next Steps

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.