Build Lean and Mean Minimal APIs in ASP.NET Core

Minimal APIs are a new, lightweight approach to building REST APIs introduced in .NET. They reduce ceremony and allow developers to focus directly on the API endpoint logic rather than controllers and actions. Benefits include fast and productive development, reduced boilerplate code, and an emphasis on business logic over configuration. Minimal APIs are great for developing microservices and containers.

Minimal APIs in ASP.NET Core

What are Minimal APIs?
  • Route handlers map requests directly to endpoint logic rather than routing through controllers and actions.
  • Leverage HttpRequest/HttpResponse for processing requests/responses
  • Use any class to encapsulate API logic, no need for dedicated controllers
  • Built on ASP.NET Core so they gain that framework's strengths like cross-platform and high-performance
  • Configuration over convention - you focus on code rather than framework conventions

Implementing Minimal APIs:

Let's dive into how to implement Minimal APIs in ASP.NET Core with detailed examples:

Minimal API, can define the endpoints right in the program.cs file. Let's make our first GET endpoint by just adding the below code to your program.cs file before app.Run() statement.
app.MapGet("/hello", () => "Hello, Minimal API!");
 
app.Run();
You can even pass the Route Parameters as below:
app.MapGet("/hello/{name}", (string name) => $"Hello, {name}!");
 
app.Run();
The above shows the basic syntax of defining routes and passing route parameters.

Congratulations! You have now successfully created your first GET Minimal API.

We'll build this out into a full CRUD API next.

Let's create a below Product class and we will perform the CRUD operation on it using the Entity Framework. In this article we will focus only building Minimal APIs. If you don't have the Entity Framework in had, first please setup using "Entity Framework Core Code First – Step by Step Guide for ASP.NET Core".
public class Product
{
    public int Id { getset; }
    public string Name { getset; }
    public decimal Price { getset; }
}
We will group all Product related endpoints under one API with help of MapGroup as below:
var productsEndPoint = app.MapGroup("/Products");
GET All Products
productsEndPoint.MapGet("/Get"async (ApplicationDbContext db) =>
    await db.Products.ToListAsync());
GET Product by ID
productsEndPoint.MapGet("/GetById/{id}"async (int id, ApplicationDbContext db) => {
    var product = await db.Products.FindAsync(id);
 
    if (product == null)
    {
        return Results.NotFound();
    }
 
    return Results.Ok(product);
});
POST to Create New Product
productsEndPoint.MapPost("/Create"async (Product item, ApplicationDbContext db) => {
    db.Add(item);
    await db.SaveChangesAsync();
    return Results.Created($"/products/{item.Id}", item);
});
PUT to Update Product
productsEndPoint.MapPut("/Update/{id}"async (int id, Product inputItem, ApplicationDbContext db) => {
    var item = await db.Products.FindAsync(id);
    if (item == nullreturn Results.NotFound();
 
    item.Name = inputItem.Name;
    item.Price = inputItem.Price;
    await db.SaveChangesAsync();
 
    return Results.NoContent();
});
DELETE to Remove Product
productsEndPoint.MapDelete("/Delete/{id}"async (int id, ApplicationDbContext db) => {
    var item = await db.Products.FindAsync(id);
 
    if (item == null)
        return Results.NotFound();
 
    db.Products.Remove(item);
 
    await db.SaveChangesAsync();
 
    return Results.Ok();
});
Lets add the swagger to our application, so that we can test the APIs right from the browser:
//Add Swagger Service
builder.Services.AddEndpointsApiExplorer();
 
builder.Services.AddSwaggerGen(c =>
{
    c.SwaggerDoc("v1"new OpenApiInfo { Title = "Products API", Version = "v1" });
});
Add the above code before app.Build();
app.UseSwagger();
 
app.UseSwaggerUI(c =>
{
    c.SwaggerEndpoint("/swagger/v1/swagger.json""Products API");
});
Add the above code before app.Run();

When you run the application you can see the list of all above APIs we built in swagger:

Minimal APIs in Swagger

This implements a complete, persistent CRUD API for data items using EF Core.

How Minimal APIs Differ from Traditional Controller APIs?

Controllers
  • Built around controller classes and action methods
  • More ceremony - attributes and conventions
  • Follow MVC architectural pattern
[ApiController]
public class ItemsController : ControllerBase
{ 
    [HttpGet]
    public IActionResult Get() { }
}
Minimal APIs
  • Focus directly on endpoint logic
  • Very little ceremony or boilerplate code
  • Can implement in any class
app.MapGet("/GetProducts", () => {
    // endpoint logic
});
Other Differences
  • Minimal APIs good for microservices, containers
  • Controller APIs better for large monolithic apps
  • Strong tooling support for traditional APIs
  • Minimal syntax takes getting used to
So in summary, minimal APIs reduce noise and focus on expressive code over configuration while traditional controller APIs provide more structure and conventions. Choose the right approach based on app architecture preference!

Conclusion

Minimal APIs make it fast and easy to build lightweight, high-performance REST APIs by focusing on endpoint logic over configuration. They are great for microservices and containers. This post covered the basics of minimal APIs in ASP.NET Core, including differences from traditional controllers, CRUD data access with Entity Framework Core, and organizing routes.

No comments:

Powered by Blogger.