Getting Started with .NET 7 Minimal APIs

A practical guide to building lightweight, high-performance APIs in .NET 7 using the Minimal APIs framework. Learn how to get rid of the boilerplate and focus on your endpoints.

Since their introduction in .NET 6, Minimal APIs have provided a streamlined and low-ceremony way to build fast and lightweight HTTP APIs. With the release of .NET 7, this framework has matured, adding new features that make it a powerful and viable choice for a wide range of applications, from simple microservices to more complex backends.

Let's dive into how to get started with Minimal APIs in .NET 7.

What are Minimal APIs?

Minimal APIs allow you to build fully functional APIs with just a few lines of code in a single Program.cs file. They strip away the ceremony of traditional ASP.NET Core MVC controllers, eliminating the need for extensive boilerplate code. This results in applications that are easier to write, read, and maintain, especially for smaller services.

Key Benefits:

  • Less Boilerplate: No controllers, no complex startup configuration. Just endpoints.
  • Improved Performance: The streamlined pipeline and reduced overhead can lead to significant performance improvements over traditional MVC.
  • Easy to Learn: The simple, direct mapping of routes to handlers is intuitive and easy to pick up.

Creating Your First Minimal API

Getting started is as simple as a single dotnet command:

dotnet new web -o MyMinimalApi
cd MyMinimalApi

This creates a new project with a Program.cs file that looks something like this:

// Program.cs
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

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

app.Run();

That's it! This is a complete, runnable web API. You can start it with dotnet run and navigate to the root URL to see "Hello World!".

Defining Endpoints

The core of a Minimal API is mapping HTTP verbs and routes to handler functions (lambdas or methods).

// GET endpoint with a route parameter
app.MapGet("/users/{id}", (int id) => $"Fetching user {id}");

// POST endpoint that receives a JSON body
app.MapPost("/users", (User user) => 
{
    // Logic to create the user...
    return Results.Created($"/users/{user.Id}", user);
});

// A simple data record
public record User(int Id, string Name);

.NET automatically handles model binding from the route, query string, and request body, making it incredibly easy to work with data.

New in .NET 7: Route Groups

One of the most significant additions in .NET 7 was the ability to group endpoints. This helps you organize your endpoints and reduce repetitive code, especially as your API grows.

// Group all user-related endpoints under a common prefix
var usersGroup = app.MapGroup("/api/users");

usersGroup.MapGet("/", () => { /* Get all users */ });
usersGroup.MapGet("/{id}", (int id) => { /* Get user by ID */ });
usersGroup.MapPost("/", (User user) => { /* Create user */ });

This is a much cleaner way to organize your API than having a long, flat list of app.Map... calls.

New in .NET 7: Endpoint Filters

Endpoint filters are another powerful feature introduced in .NET 7. They allow you to implement cross-cutting concerns (like validation, logging, or authentication) in a clean, reusable way, similar to middleware or MVC action filters.

Example: A simple validation filter.

// A filter that validates a User object
public class UserValidationFilter : IEndpointFilter
{
    public async ValueTask<object?> InvokeAsync(EndpointFilterInvocationContext context, EndpointFilterDelegate next)
    {
        var user = context.GetArgument<User>(0);
        if (string.IsNullOrEmpty(user.Name))
        {
            return Results.BadRequest("User name cannot be empty.");
        }
        return await next(context);
    }
}

// Apply the filter to an endpoint
app.MapPost("/users", (User user) => { /* ... */ })
   .AddEndpointFilter<UserValidationFilter>();

Now, the validation logic will run for this endpoint before the handler is ever invoked, keeping your handler code clean and focused on its core responsibility.

Conclusion

Minimal APIs in .NET 7 have matured into a powerful and production-ready framework for building APIs. By stripping away unnecessary boilerplate and providing powerful new features like route groups and endpoint filters, they allow you to build high-performance services faster than ever before. For your next microservice or simple web API, give Minimal APIs a try—you might find you don't miss the controllers at all.