ASP.NET - Minimal APIs in ASP.NET Core

Minimal APIs are a lightweight approach for building HTTP APIs in ASP.NET Core with very little setup and configuration. They were introduced in ASP.NET Core 6 to simplify API development by reducing the amount of boilerplate code required in traditional controller-based applications.

Instead of creating controllers, action methods, and extensive routing configurations, Minimal APIs allow developers to define endpoints directly in the Program.cs file or related files using concise syntax. This approach is especially useful for microservices, lightweight backend services, serverless applications, and rapid API development.

Purpose of Minimal APIs

Traditional ASP.NET Core Web API applications generally involve:

  • Controllers

  • Routing attributes

  • Dependency injection inside constructors

  • Action methods

  • Startup configuration

Although this structure is powerful for large enterprise applications, it may become unnecessary for small APIs or services. Minimal APIs aim to:

  • Reduce development complexity

  • Improve readability

  • Increase development speed

  • Lower the amount of code required

  • Simplify endpoint creation

Minimal APIs provide a functional style of API development where routes and handlers are declared directly.

Basic Structure of a Minimal API

A Minimal API application begins with a simplified configuration in the Program.cs file.

Example:

var builder = WebApplication.CreateBuilder(args);

var app = builder.Build();

app.MapGet("/", () => "Welcome to Minimal API");

app.Run();

Explanation

  • WebApplication.CreateBuilder(args) initializes the application builder.

  • builder.Build() creates the application instance.

  • MapGet() defines an HTTP GET endpoint.

  • app.Run() starts the web server.

When the root URL is accessed, the API returns the message:

Welcome to Minimal API

HTTP Methods Supported

Minimal APIs support all major HTTP methods.

GET Request

app.MapGet("/products", () =>
{
    return new List<string> { "Laptop", "Mobile", "Tablet" };
});

POST Request

app.MapPost("/products", (Product product) =>
{
    return Results.Created($"/products/{product.Id}", product);
});

PUT Request

app.MapPut("/products/{id}", (int id, Product product) =>
{
    return Results.Ok(product);
});

DELETE Request

app.MapDelete("/products/{id}", (int id) =>
{
    return Results.Ok($"Deleted Product {id}");
});

Working with Parameters

Minimal APIs can automatically bind parameters from:

  • Route values

  • Query strings

  • Request body

  • Services

  • Headers

Route Parameter Example

app.MapGet("/users/{id}", (int id) =>
{
    return $"User ID: {id}";
});

If the URL is:

/users/10

The response becomes:

User ID: 10

Query String Example

app.MapGet("/search", (string keyword) =>
{
    return $"Searching for {keyword}";
});

URL:

/search?keyword=phone

Model Binding

Minimal APIs support automatic binding of JSON request bodies into objects.

Example Model

public class Product
{
    public int Id { get; set; }
    public string Name { get; set; }
}

API Endpoint

app.MapPost("/addproduct", (Product product) =>
{
    return Results.Ok(product);
});

JSON Request

{
  "id": 1,
  "name": "Laptop"
}

ASP.NET Core automatically converts the JSON into a Product object.

Dependency Injection in Minimal APIs

Dependency Injection works seamlessly in Minimal APIs.

Service Registration

builder.Services.AddSingleton<MessageService>();

Service Class

public class MessageService
{
    public string GetMessage()
    {
        return "Service Injected Successfully";
    }
}

Injecting Service into Endpoint

app.MapGet("/message", (MessageService service) =>
{
    return service.GetMessage();
});

The framework automatically injects the service instance.

Using Entity Framework Core

Minimal APIs work effectively with Entity Framework Core for database operations.

Register DbContext

builder.Services.AddDbContext<AppDbContext>(options =>
    options.UseSqlServer(builder.Configuration.GetConnectionString("Default")));

Database Endpoint Example

app.MapGet("/employees", async (AppDbContext db) =>
{
    return await db.Employees.ToListAsync();
});

This endpoint retrieves employee records from the database.

Validation in Minimal APIs

Input validation can be implemented manually or using libraries such as FluentValidation.

Manual Validation Example

app.MapPost("/register", (User user) =>
{
    if (string.IsNullOrEmpty(user.Name))
    {
        return Results.BadRequest("Name is required");
    }

    return Results.Ok(user);
});

Returning Different Types of Results

Minimal APIs provide helper methods through the Results class.

Common Result Types

Method Purpose
Results.Ok() Returns HTTP 200
Results.Created() Returns HTTP 201
Results.NotFound() Returns HTTP 404
Results.BadRequest() Returns HTTP 400
Results.Unauthorized() Returns HTTP 401

Example

app.MapGet("/product/{id}", (int id) =>
{
    if (id <= 0)
    {
        return Results.BadRequest();
    }

    return Results.Ok($"Product {id}");
});

Route Grouping

Route grouping helps organize related endpoints.

Example

var productGroup = app.MapGroup("/products");

productGroup.MapGet("/", GetProducts);
productGroup.MapPost("/", AddProduct);

This improves maintainability in large applications.

Middleware Integration

Minimal APIs support ASP.NET Core middleware.

Example

app.UseHttpsRedirection();

app.UseAuthentication();

app.UseAuthorization();

Middleware can handle:

  • Authentication

  • Authorization

  • Logging

  • Exception handling

  • CORS

  • Rate limiting

Authentication and Authorization

Minimal APIs support JWT authentication and role-based authorization.

Example

app.MapGet("/admin", () =>
{
    return "Admin Data";
}).RequireAuthorization();

Only authenticated users can access the endpoint.

API Versioning

Versioning can be implemented to manage evolving APIs.

Example:

/api/v1/products
/api/v2/products

This prevents breaking older client applications.

Advantages of Minimal APIs

Faster Development

Developers can create APIs quickly with minimal setup.

Reduced Boilerplate Code

No need for controllers and repetitive configurations.

Better Performance

Minimal APIs are optimized for lightweight execution.

Ideal for Microservices

Perfect for small independent services.

Easy Learning Curve

Beginners can understand the API structure more easily.

Limitations of Minimal APIs

Not Ideal for Very Large Applications

Large enterprise systems may become difficult to manage without structured controllers.

Reduced Separation of Concerns

Business logic can accidentally become mixed with routing logic.

Complex Applications Need Better Organization

As APIs grow, developers may need additional architecture patterns.

Minimal APIs vs Traditional Controllers

Feature Minimal APIs Controller APIs
Code Size Smaller Larger
Complexity Low Medium to High
Performance Faster Slightly Slower
Structure Simple Organized
Best For Microservices Enterprise Apps

Real-World Use Cases

Minimal APIs are commonly used in:

  • Microservices architecture

  • Cloud-native applications

  • Lightweight backend systems

  • IoT services

  • Internal APIs

  • Rapid prototyping

  • Serverless APIs

Best Practices

Keep Endpoints Small

Each endpoint should perform a single responsibility.

Use Route Groups

Organize related endpoints together.

Separate Business Logic

Move complex logic into services instead of writing everything inside endpoints.

Implement Proper Validation

Always validate user input.

Use Dependency Injection

Avoid directly creating objects inside endpoints.

Enable Logging and Exception Handling

Use middleware for centralized error management.

Conclusion

Minimal APIs in ASP.NET Core provide a modern, lightweight, and efficient way to build HTTP APIs with minimal configuration. They reduce boilerplate code while maintaining the powerful features of ASP.NET Core such as dependency injection, middleware, authentication, and database integration.

They are highly suitable for small to medium-sized applications, microservices, and rapid API development. However, for very large enterprise systems, developers may still prefer traditional controller-based architectures for better structure and maintainability.