Ответ
В 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 для организации кода. Для сложной логики валидации и обработки выносите код в отдельные методы или классы, а в лямбде эндпоинта оставляйте только вызов.