A Minimalist introduction to the Minimal API in .NET 6

Play this article

Minimal API is the extremely simple way to write HTTP API with minimum dependencies. Its normal controller based API minus all its ceremonies.

The Minimalist get call is

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

The call specifies a route (e.g., "/") and a callback that will be executed once a request matching the route and verb is received.

Now, Let’s see how the code will look like using Minimal APIs in .NET 6

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
app.MapGet("/", () => "Hello World!");
app.Run();

Program.PNG

You can see the Program.cs file in your ASP.NET Core project, containing the hello world API.

In comparison to the previous version of controller-based APIs, how minimal is it? What is missing?

  • Startup.cs
  • Global Using Statements
  • Controller Classes

Instead of a Startup.cs class with places to set up services and middleware, it's all done in this very simple top-level program in Program.cs

Routing

Minimal API mapping patterns are a lot like pattern matching in MVC controllers.

Get call for route “/api/users”

app.MapGet("/api/users", () => new User()
{
    Id = 1,
    Name = "user”    
});

Get call for route “/api/users” with parameters

app.MapGet("/api/users/{id:int}", (int id) => new User()
{
    Id = id,
    Name = "user " + id
});

Registering Services

In the Minimal api we can use the builder object to access the services.

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddDbContext<UserDBContext>();
builder.Services.AddTransient<IUserRepo, UserRepo>();

We can use the Services object on the application builder to add any services we need.

To use these services add them to the lambda expression parameter .

app.MapGet("/api/users", async (IUserRepo userRepo) =>
{
   return await userRepo.GetUsersAsync();
});

It’s unlike controller based API where dependencies are injected at class level , in Minimal API dependencies are injected into the lambda expression.

How about other HTTP Verbs ?

There are methods for the different types of verbs. These include:

  • MapGet
  • MapPost
  • MapPut
  • MapDelete
app.MapPost("/users", async (User model, IUserRepo userRepo) =>
{
    //..
});
app.MapPut("/users/{id}", async (int id, User model, IUserRepo userRepo) =>
{

});
app.MapMethods("/user", new[] { "PATCH" },
                     async (IUserRepo userRepo) =>  { });

How about Status Codes ?

We need a way of controlling what status code to return.These are handled with the Results static class.

app.MapGet("/api/users", async (IUserRepo userRepo) =>
{
    return Results.Ok(await userRepo.GetUsersAsync());
});

Securing the API

Even though Minimal API works with Authorization and Authentication middleware, we need to specify access control at the API level. To require authorization

app.MapGet("/api/users", async (IUserRepo userRepo) =>
{
    return Results.Ok(await userRepo.GetUsersAsync());
}).RequireAuthorization();

To allow anonymous users

app.MapGet("/api/users", async (IUserRepo userRepo) =>
{
    return Results.Ok(await userRepo.GetUsersAsync());
}).AllowAnonymous();

Minimal APIs are a good starting point for creating API’s. When the project matures and becomes more complex we may have to move towards controller-based APIs.