minimal-apis

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Minimal APIs Skill

Minimal APIs 技能文档

Sorcha uses .NET 10 Minimal APIs exclusively—NEVER MVC controllers. All endpoints are organized via
MapGroup()
route grouping with extension methods in
Endpoints/
folders. OpenAPI documentation uses Scalar (NOT Swagger).
Sorcha 仅使用 .NET 10 Minimal APIs,绝不使用 MVC 控制器。所有端点通过
MapGroup()
路由分组进行组织,扩展方法存放在
Endpoints/
文件夹中。OpenAPI 文档使用 Scalar(而非 Swagger)生成。

Quick Start

快速开始

Route Group with Authorization

带授权的路由分组

csharp
// src/Services/Sorcha.Wallet.Service/Endpoints/WalletEndpoints.cs
public static IEndpointRouteBuilder MapWalletEndpoints(this IEndpointRouteBuilder app)
{
    var walletGroup = app.MapGroup("/api/v1/wallets")
        .WithTags("Wallets")
        .RequireAuthorization("CanManageWallets");

    walletGroup.MapPost("/", CreateWallet)
        .WithName("CreateWallet")
        .WithSummary("Create a new wallet")
        .WithDescription("Creates a new HD wallet with the specified algorithm");

    walletGroup.MapGet("/{address}", GetWallet)
        .WithName("GetWallet")
        .WithSummary("Get wallet by address");

    return app;
}
csharp
// src/Services/Sorcha.Wallet.Service/Endpoints/WalletEndpoints.cs
public static IEndpointRouteBuilder MapWalletEndpoints(this IEndpointRouteBuilder app)
{
    var walletGroup = app.MapGroup("/api/v1/wallets")
        .WithTags("Wallets")
        .RequireAuthorization("CanManageWallets");

    walletGroup.MapPost("/", CreateWallet)
        .WithName("CreateWallet")
        .WithSummary("Create a new wallet")
        .WithDescription("Creates a new HD wallet with the specified algorithm");

    walletGroup.MapGet("/{address}", GetWallet)
        .WithName("GetWallet")
        .WithSummary("Get wallet by address");

    return app;
}

Endpoint Handler with DI

依赖注入的端点处理器

csharp
private static async Task<IResult> CreateWallet(
    [FromBody] CreateWalletRequest request,
    WalletManager walletManager,
    HttpContext context,
    ILogger<Program> logger,
    CancellationToken cancellationToken = default)
{
    try
    {
        var (wallet, mnemonic) = await walletManager.CreateWalletAsync(...);
        return Results.Created($"/api/v1/wallets/{wallet.Address}", response);
    }
    catch (ArgumentException ex)
    {
        return Results.BadRequest(new ProblemDetails { Title = "Invalid Request", Detail = ex.Message });
    }
}
csharp
private static async Task<IResult> CreateWallet(
    [FromBody] CreateWalletRequest request,
    WalletManager walletManager,
    HttpContext context,
    ILogger<Program> logger,
    CancellationToken cancellationToken = default)
{
    try
    {
        var (wallet, mnemonic) = await walletManager.CreateWalletAsync(...);
        return Results.Created($"/api/v1/wallets/{wallet.Address}", response);
    }
    catch (ArgumentException ex)
    {
        return Results.BadRequest(new ProblemDetails { Title = "Invalid Request", Detail = ex.Message });
    }
}

Key Concepts

核心概念

ConceptUsageExample
Route GroupsShared config for related endpoints
app.MapGroup("/api/v1/wallets").WithTags("Wallets")
TypedResultsType-safe return values
Results<Ok<T>, NotFound, ValidationProblem>
OpenAPI Metadata
.WithName()
,
.WithSummary()
Required on all endpoints
Authorization
.RequireAuthorization("Policy")
Apply to groups or individual endpoints
AllowAnonymousPublic endpoints
.AllowAnonymous()
on login routes
Cache OutputRedis output caching
.CacheOutput(p => p.Expire(...).Tag("tag"))
概念用法示例
路由分组(Route Groups)为相关端点共享配置
app.MapGroup("/api/v1/wallets").WithTags("Wallets")
类型化结果(TypedResults)类型安全的返回值
Results<Ok<T>, NotFound, ValidationProblem>
OpenAPI 元数据
.WithName()
.WithSummary()
所有端点必须配置
授权(Authorization)
.RequireAuthorization("Policy")
应用于分组或单个端点
允许匿名访问(AllowAnonymous)公开端点登录路由上使用
.AllowAnonymous()
输出缓存(Cache Output)Redis输出缓存
.CacheOutput(p => p.Expire(...).Tag("tag"))

Common Patterns

常见模式

TypedResults for Explicit Return Types

使用TypedResults定义明确的返回类型

csharp
private static async Task<Results<Ok<TokenResponse>, UnauthorizedHttpResult, ValidationProblem>> Login(
    LoginRequest request,
    ITokenService tokenService)
{
    if (string.IsNullOrWhiteSpace(request.Email))
        return TypedResults.ValidationProblem(new Dictionary<string, string[]>
        {
            ["email"] = ["Email is required"]
        });

    var token = await tokenService.LoginAsync(request);
    if (token == null) return TypedResults.Unauthorized();

    return TypedResults.Ok(token);
}
csharp
private static async Task<Results<Ok<TokenResponse>, UnauthorizedHttpResult, ValidationProblem>> Login(
    LoginRequest request,
    ITokenService tokenService)
{
    if (string.IsNullOrWhiteSpace(request.Email))
        return TypedResults.ValidationProblem(new Dictionary<string, string[]>
        {
            ["email"] = ["Email is required"]
        });

    var token = await tokenService.LoginAsync(request);
    if (token == null) return TypedResults.Unauthorized();

    return TypedResults.Ok(token);
}

Query Parameters with Defaults

带默认值的查询参数

csharp
walletGroup.MapGet("/{address}/addresses", ListAddresses);

private static async Task<IResult> ListAddresses(
    string address,                              // Route parameter
    [FromQuery] string? type = null,             // Optional filter
    [FromQuery] bool? used = null,               // Optional filter
    [FromQuery] int page = 1,                    // Default pagination
    [FromQuery] int pageSize = 50)
csharp
walletGroup.MapGet("/{address}/addresses", ListAddresses);

private static async Task<IResult> ListAddresses(
    string address,                              // 路由参数
    [FromQuery] string? type = null,             // 可选过滤器
    [FromQuery] bool? used = null,               // 可选过滤器
    [FromQuery] int page = 1,                    // 默认分页页码
    [FromQuery] int pageSize = 50)               // 默认分页大小

See Also

参考链接

  • patterns - Endpoint organization, error handling, caching
  • workflows - Creating new endpoints, adding authorization
  • patterns - 端点组织、错误处理、缓存
  • workflows - 创建新端点、添加授权配置

Related Skills

相关技能

  • See the aspire skill for service orchestration and configuration
  • See the scalar skill for OpenAPI documentation UI
  • See the jwt skill for authentication and authorization setup
  • See the redis skill for output caching configuration
  • See the signalr skill for real-time endpoint notifications
  • 查看 aspire 技能文档,了解服务编排与配置
  • 查看 scalar 技能文档,了解OpenAPI文档UI配置
  • 查看 jwt 技能文档,了解认证与授权设置
  • 查看 redis 技能文档,了解输出缓存配置
  • 查看 signalr 技能文档,了解实时端点通知

Documentation Resources

文档资源

Fetch latest ASP.NET Core Minimal APIs documentation with Context7.
How to use Context7:
  1. Use
    mcp__context7__resolve-library-id
    to search for "aspnetcore"
  2. Prefer
    /websites/learn_microsoft_en-us_aspnet_core
    for official docs
  3. Query with
    mcp__context7__query-docs
Library ID:
/websites/learn_microsoft_en-us_aspnet_core
Recommended Queries:
  • "minimal apis route groups"
  • "minimal apis typed results"
  • "minimal apis authorization"
  • "minimal apis openapi documentation"
使用Context7获取最新的ASP.NET Core Minimal APIs文档。
Context7 使用方法:
  1. 使用
    mcp__context7__resolve-library-id
    搜索“aspnetcore”
  2. 优先选择
    /websites/learn_microsoft_en-us_aspnet_core
    官方文档
  3. 使用
    mcp__context7__query-docs
    进行查询
库ID:
/websites/learn_microsoft_en-us_aspnet_core
推荐查询关键词:
  • "minimal apis route groups"
  • "minimal apis typed results"
  • "minimal apis authorization"
  • "minimal apis openapi documentation"