Building Modern APIs with Minimal APIs and OpenAPI in .NET 8 (Expanded Guide)

.NET 8 continues to mature the Minimal APIs feature set, making it easier than ever to build fast, concise, and powerful web APIs without the complexity of full MVC stacks. In this extended guide, you’ll learn how to leverage Minimal APIs in real-world scenarios, implement OpenAPI documentation, secure your endpoints, structure your routes, and optimize performance.


⚡ What Are Minimal APIs?

Minimal APIs were introduced in .NET 6 as a lightweight way to create HTTP endpoints with minimal ceremony. Unlike traditional MVC controllers, Minimal APIs:

  • Don’t require controllers or action methods
  • Work well for microservices and internal APIs
  • Support dependency injection directly via method parameters

Hello World Example

var app = WebApplication.Create();

app.MapGet("/", () => "Hello, world!");

app.Run();


🆕 What’s New in .NET 8 for Minimal APIs?

.NET 8 significantly improves upon Minimal APIs with new features like:

🧩 Route Grouping

Organize related endpoints:

var productsGroup = app.MapGroup("/products");
productsGroup.MapGet("/", GetAllProducts);
productsGroup.MapPost("/", CreateProduct);

🧪 Endpoint Filters

Inject reusable behaviors into endpoints (similar to middleware):

app.MapPost("/products", CreateProduct)
   .AddEndpointFilter(async (ctx, next) => {
       // Example: Validate model
       var model = ctx.GetArgument<Product>(0);
       if (string.IsNullOrWhiteSpace(model.Name))
           return Results.BadRequest("Name is required");

       return await next(ctx);
   });

📖 Typed Results

Enable rich response typing for better tooling and validation:

Results<Ok<Product>, NotFound> GetProduct(int id)

🔧 Built-in OpenAPI Metadata

Attach Swagger metadata directly to routes:

app.MapGet("/weather", GetWeather)
   .WithName("GetWeather")
   .WithTags("Forecast")
   .WithOpenApi();


📚 Documenting APIs with Swagger and OpenAPI

Minimal APIs now have full integration with Swagger using just a few lines:

Setup

builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

Middleware

app.UseSwagger();
app.UseSwaggerUI();

Result:

Automatically generates an OpenAPI schema and Swagger UI for interacting with your API endpoints.


🔐 Securing APIs: Auth & Authorization

Step 1: Configure JWT

builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    .AddJwtBearer(options => {
        options.Authority = "https://your-auth-provider";
        options.Audience = "your-api";
    });

builder.Services.AddAuthorization();

Step 2: Secure Endpoints

app.MapGet("/admin/stats", GetStats)
   .RequireAuthorization("AdminOnly")
   .WithTags("Admin");

Step 3: Policy-Based Access

builder.Services.AddAuthorization(options => {
    options.AddPolicy("AdminOnly", policy =>
        policy.RequireRole("Admin"));
});


📐 Designing RESTful API Structure

CRUD Pattern for Resources:

app.MapGet("/products", GetAllProducts);
app.MapGet("/products/{id}", GetProductById);
app.MapPost("/products", CreateProduct);
app.MapPut("/products/{id}", UpdateProduct);
app.MapDelete("/products/{id}", DeleteProduct);

Example Return:

Results<Ok<Product>, NotFound> GetProductById(int id)
{
    var product = repo.Get(id);
    return product is not null ? Results.Ok(product) : Results.NotFound();
}


📊 Performance Benchmarks

Minimal APIs are more efficient than MVC counterparts:

BenchmarkMinimal APIASP.NET MVC
Cold Start Time~10ms~100ms
Requests/Second~2.1M~1.3M
Memory UsageLowerHigher

Ideal for:

  • Serverless scenarios
  • Containerized deployments
  • APIs with frequent scale-out needs

🧰 Testing & Validation

Use Microsoft.AspNetCore.Mvc.Testing with WebApplicationFactory to test Minimal APIs just like MVC apps.

var client = factory.CreateClient();
var result = await client.GetAsync("/products");
Assert.Equal(HttpStatusCode.OK, result.StatusCode);

Use FluentValidation or endpoint filters for model validation.


🔄 Comparing Minimal API vs Controller-based API

FeatureMinimal APIController API
BoilerplateMinimalVerbose
Startup TimeFasterSlower
Middleware HooksCustom filtersAction filters
OpenAPI SupportBuilt-inRequires Swashbuckle
Recommended ForMicroservices, serverlessFull-featured apps

🛠 Tools and Libraries

  • Swashbuckle.AspNetCore: Enhanced Swagger UI
  • FluentValidation: Model validation
  • Asp.Versioning.Http: API versioning for Minimal APIs
  • MediatR: Add CQRS patterns with minimal boilerplate

🧠 Best Practices for Minimal APIs in Production

✅ Use endpoint grouping to organize routes ✅ Apply consistent naming and structure ✅ Generate OpenAPI schema for every route ✅ Secure APIs with JWT and RBAC ✅ Write integration tests with WebApplicationFactory ✅ Enable response compression and caching middleware


📎 Sample Project Structure

- Program.cs
- Endpoints/
  - ProductsEndpoints.cs
  - AuthEndpoints.cs
- Models/
  - Product.cs
- Services/
  - IProductService.cs
  - ProductService.cs
- appsettings.json


📌 Summary

Minimal APIs in .NET 8 are now a production-ready choice for modern API development. With better routing, filters, OpenAPI support, and performance advantages, they are ideal for microservices, internal tools, and performance-critical APIs.

Start simple. Scale as needed. And write less boilerplate.

Leave a comment