Minimal APIs vs MVC Controllers: A Comparative Guide


In 2021, with the release of .NET 6, Microsoft introduced one more tool for building services over the web — the Minimal API. Unfortunately, this new tool was not filling a gap in the ASP.NET Core ecosystem but rather advancing on MVC Controllers, the traditional way of exposing HTTP endpoints returning HTML, JSON, or other content. Controllers are a proven and extremely flexible framework for handling requests, but Minimal APIs brought the allure of leaner code and faster paths from request to response

It was sold as a lightweight alternative to controllers and as such ideal for microservices, serverless functions, or quick prototypes. Controllers, on the hand, in comparison were projected as overkill. Are minimal API really a good deal or just the minimalist cousin of controllers desperately trying to catch up?

The Runtime Pathway

ASP.NET Core supports several types of endpoints. Some, like classic MVC controller actions, SignalR hubs, and gRPC services, are natively supported. Others, such as GraphQL endpoints, require external packages.

Minimal API endpoints are yet another native type of ASP.NET Core endpoint.

All these endpoint types are ultimately processed through the same runtime pathway. Regardless of the specific endpoint type, the journey of an HTTP request begins when IIS (if present) accepts it and forwards it to the configured ASP.NET Core application. In an ASP.NET Core hosting model, Kestrel is the embedded web server that actually receives and processes the request inside the .NET runtime environment.

Once the request enters Kestrel, it passes through the middleware pipeline — a sequence of components that inspect, modify, or act upon the request in the order they were registered. At the end of this chain, the matched endpoint is invoked — whether it’s a controller action, a Minimal API handler, or something else. The generated response then travels back through the middleware in reverse order until it reaches the server gateway, where IIS (if used) or Kestrel itself sends it back to the client.

This pathway is identical for all endpoint types; what changes is the style, philosophy, and execution model of the endpoint itself. Beyond these conceptual differences, the most significant technical distinction between Minimal APIs and other ASP.NET Core endpoints lies in how routing binds requests to handlers—and at what stage those handlers are executed.

Let’s unpack what happens around the UseRouting standard middleware and how it differs between Minimal APIs and MVC controllers and other endpoints.

Inside ASP.NET Core Routing

In ASP.NET Core, UseRouting is the middleware responsible for matching incoming HTTP requests to the endpoints defined by the application—whether those are Minimal API routes, controller actions, Razor Pages, or other endpoints.

In regular ASP.NET Core applications, you must explicitly call UseRouting in the middleware pipeline. For Minimal APIs, this explicit call is not strictly necessary, because the routing logic is implicitly invoked when you register endpoints using methods like MapGet, MapPost, and others.

var app = WebApplication.Create(args);
app.UseRouting();  // Optional for Minimal API endpoints only
app.MapGet("/hello", () => "Hello World!");
app.Run();

As a result, the lambda you provide to MapGet, MapPost, and similar methods becomes the endpoint handler that executes when a request matches the route. When you call app.Run to start the application, the middleware pipeline is already composed with routing. Therefore, if a request hits the routing mechanism and matches a route like /hello, the corresponding handler executes immediately—without requiring additional middleware, unlike MVC controller actions or other types of endpoints.

Routing is more involved and sophisticated when working with MVC controllers.

In that case, routes are discovered through either conventional mapping or attribute routing. Additionally, the binding to the actual controller action methods occurs later in the pipeline via the specialized MVC middleware.

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers();
var app = builder.Build();

app.UseRouting();
app.UseEndpoints(endpoints =>
{
    endpoints.MapControllers();
});

app.Run();

The MVC middleware—specifically UseEndpoints—invokes the MVC framework, which then executes controller action filters, performs model binding, runs validation, and so on. In summary, UseRouting only matches the route; the actual controller action is executed later when UseEndpoints runs and dispatches the request to the MVC middleware.

Summary

From a purely functional perspective, there is no difference between Minimal API endpoints and MVC controller endpoints—both process requests to generate a response and execute within the same runtime pipeline. The primary difference lies in the time it takes to go from endpoint discovery to actual code execution. This latency is nearly zero for Minimal APIs.

Another difference is that the internal pipeline leading to the execution of the lambda or method is slightly shorter for Minimal APIs. However, with each new version of .NET, this pipeline may become longer, gradually approaching the full length of the pipeline used by MVC controller actions.

Published by D. Esposito

Software person since 1992

Leave a comment