Какие способы настройки маршрутизации в Minimal APIs ты знаешь?

«Какие способы настройки маршрутизации в Minimal APIs ты знаешь?» — вопрос из категории ASP.NET Core, который задают на 25% собеседований C# Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

В Minimal APIs маршрутизация настраивается декларативно с помощью методов Map* и их перегрузок. Вот основные приёмы.

1. Базовые маршруты с параметрами

app.MapGet("/", () => "Hello World!");
app.MapGet("/users/{id}", (int id) => $"User ID: {id}");
app.MapPost("/users", (User user) => Results.Created($"/users/{user.Id}", user));

2. Ограничения типов и дополнительные параметры в маршруте Параметры можно ограничивать по типу и делать опциональными.

// Строго типизированный параметр
app.MapGet("/products/{id:int}", (int id) => ...);

// Ограничение Guid
app.MapGet("/documents/{docId:guid}", (Guid docId) => ...);

// Опциональный параметр (задаётся через параметр метода с значением по умолчанию)
app.MapGet("/search/{term?}", (string term = "default") => $"Searching for: {term}");

// "Catch-all" параметр
app.MapGet("/files/{*path}", (string path) => $"File path: {path}");

3. Группировка маршрутов с MapGroup Позволяет задать общий префикс, фильтры и политики для набора эндпоинтов.

var api = app.MapGroup("/api");
api.MapGet("/", () => "API Root");

var users = api.MapGroup("/users");
users.MapGet("/", () => "All users");
users.MapGet("/{id}", (int id) => $"User {id}");

// Группа с предварительной конфигурацией
var admin = app.MapGroup("/admin")
               .RequireAuthorization("AdminPolicy")
               .WithTags("Admin");
admin.MapGet("/dashboard", () => "Admin Dashboard");

4. Фильтрация маршрутов (Route Filters) Позволяют выполнять код до (Before) и после (After) обработчика эндпоинта.

app.MapGet("/secure", () => "Secret data")
   .AddEndpointFilter(async (context, next) =>
   {
       // Логика перед вызовом handler
       var result = await next(context);
       // Логика после вызова handler
       return result;
   });

5. Кастомные привязки параметров Можно реализовать интерфейс BindAsync в своём типе, чтобы Minimal API знал, как создать его из контекста запроса.

public record CustomParam(string Value)
{
    public static ValueTask<CustomParam?> BindAsync(HttpContext context) => ...
}

app.MapGet("/custom", (CustomParam param) => param.Value);

6. Интеграция с OpenAPI (Swagger) Методы WithName, WithTags, WithDescription и WithOpenApi для документирования.

app.MapGet("/products/{id}", (int id) => ...)
   .WithName("GetProductById")
   .WithTags("Products")
   .WithSummary("Returns a product by its ID")
   .Produces<Product>(200)
   .Produces(404);

Совет: Используйте MapGroup для организации кода. Для сложной логики валидации и обработки выносите код в отдельные методы или классы, а в лямбде эндпоинта оставляйте только вызов.