Codecademy Logo

ASP.NET Minimal API in Depth

Related learning

  • Learn how to build fast, secure, and maintainable web apps with ASP.NET and the Razor Pages architecture.
    • With Certificate
    • Intermediate.
      20 hours
  • Learn how to build fast, secure, and maintainable web apps with ASP.NET and the Razor Pages architecture.
    • With Certificate
    • Intermediate.
      20 hours

ASP.NET Core Minimal APIs

In ASP.NET Core Minimal APIs, separation of concerns is achieved by moving endpoint definitions from Program.cs into separate feature-specific files using extension methods. This approach improves maintainability as applications grow by grouping related endpoints together and reducing complexity in the main program file.

MapGroup() in ASP.NET

In ASP.NET Core Minimal APIs, the MapGroup() method creates endpoint groups sharing a common URL prefix, reducing repetition and improving organization. Endpoint groups allow related routes to be defined once and applied consistently across multiple endpoints.

// Create a group for book endpoints
var booksGroup = app.MapGroup("/api/books");
// Define endpoints within the group
booksGroup.MapGet("/", () => booksList);
booksGroup.MapPost("/", (Book book) => Results.Created($"/api/books/{book.Id}", book));
booksGroup.MapGet("/{id}", (int id) => FindBook(id));
// Nested group for book reviews
var reviewsGroup = booksGroup.MapGroup("/{bookId}/reviews");
reviewsGroup.MapGet("/", (int bookId) => GetReviews(bookId));

ASP.NET TypedResults

In ASP.NET Core Minimal APIs, TypedResults provides strongly-typed HTTP responses that enhance API documentation and enable better client code generation. Unlike the regular Results class, TypedResults includes explicit type information that improves compile-time checking and Swagger schema generation

// Using TypedResults with explicit type information
app.MapGet("/api/books", () => TypedResults.Ok<List<Book>>(books));
// Type-safe handling of success and error cases
app.MapGet("/api/books/{id}", (int id) =>
{
var book = bookList.FirstOrDefault(b => b.Id == id);
return book is not null
? TypedResults.Ok<Book>(book)
: TypedResults.NotFound();
});
// Creating resources with proper status code
app.MapPost("/api/books", (Book book) =>
TypedResults.Created<Book>($"/api/books/{book.Id}", book));

ASP.NET Core Parameters

In ASP.NET Core Minimal APIs, parameter binding automatically maps data from HTTP requests to endpoint handler parameters based on parameter names. The framework intelligently determines the binding source without requiring explicit configuration in most cases.

When more control is needed, explicit binding attributes specify exact data sources.

// Automatic binding
app.MapGet("/api/books/{id}", (int id, string title) =>
$"Book ID: {id}, Title filter: {title}");
// id binds from route, title from query string
// Explicit binding with attributes
app.MapGet("/api/catalog/{category}",
([FromRoute] string category,
[FromQuery] decimal maxPrice,
[FromHeader(Name = "Accept-Language")] string language) =>
$"Category: {category}, Max Price: {maxPrice}, Language: {language}");

ASP.NET Core Error Handling

In ASP.NET Core Minimal APIs, structured error handling returns standardized problem details responses conforming to RFC 7807, providing consistent error reporting across all endpoints. The TypedResults.Problem() method generates these structured JSON responses with predefined fields like type, title, status, and detail.

app.MapGet("/api/books/{id}", (int id) =>
{
var book = books.FirstOrDefault(b => b.Id == id);
if (book == null)
{
return TypedResults.Problem(
detail: $"Book with ID {id} not found.",
statusCode: StatusCodes.Status404NotFound,
title: "Resource Not Found"
);
}
return TypedResults.Ok(book);
});

ASP.NET Core Filters

In ASP.NET Core Minimal APIs, endpoint filters provide middleware-like capabilities at the endpoint level, enabling cross-cutting concerns like logging, validation, and caching without cluttering handler code. Filters implement the IEndpointFilter interface with pre-processing before and post-processing after endpoint execution.

// Define a filter
public class LogFilter : IEndpointFilter
{
public async ValueTask<object?> InvokeAsync(
EndpointFilterInvocationContext context,
EndpointFilterDelegate next)
{
Console.WriteLine("Request started");
var result = await next(context);
Console.WriteLine("Request completed");
return result;
}
}
// Apply to endpoint or group
app.MapPost("/api/books", (Book b) => Results.Created($"/api/books/{b.Id}", b))
.AddEndpointFilter<LogFilter>();

ASP.NET Core DI

In ASP.NET Core Minimal APIs, dependency injection simplifies service access by injecting dependencies directly as endpoint handler parameters. This eliminates the need for controller classes with constructor injection, making endpoints more concise.

Services are registered in the DI container during startup and automatically resolved when endpoints are invoked.

// Register services in the DI container
builder.Services.AddScoped<BookService>();
// Inject service directly in endpoint handler
app.MapGet("/api/books", (BookService service) =>
{
var books = service.GetBooks();
return Results.Ok(books);
});
// Combine with route parameters and other bindings
app.MapGet("/api/books/{id}", (int id, BookService service) =>
{
var book = service.GetBooks().FirstOrDefault(b => b.Id == id);
return book is null ? Results.NotFound() : Results.Ok(book);
});

ASP.NET Core Security

In ASP.NET Core Minimal APIs, security is implemented through authentication middleware and endpoint-specific authorization requirements. The framework provides a fluent API to configure security services during startup and apply authorization rules to individual endpoints or groups.

// Configure authentication and authorization
builder.Services.AddAuthentication("Bearer").AddJwtBearer();
builder.Services.AddAuthorization();
// Apply middleware in the request pipeline
app.UseAuthentication();
app.UseAuthorization();
// Secure individual endpoint - requires any authenticated user
app.MapGet("/api/books", () => books)
.RequireAuthorization();
// Secure endpoint with role requirement
app.MapDelete("/api/books/{id}", (int id) => DeleteBook(id))
.RequireAuthorization(policy => policy.RequireRole("Admin"));
// Secure all endpoints in a group
var secureGroup = app.MapGroup("/api/admin")
.RequireAuthorization();

Learn more on Codecademy

  • Learn how to build fast, secure, and maintainable web apps with ASP.NET and the Razor Pages architecture.
    • With Certificate
    • Intermediate.
      20 hours
  • Learn how to build fast, secure, and maintainable web apps with ASP.NET and the Razor Pages architecture.
    • With Certificate
    • Intermediate.
      20 hours