推荐使用 mapgroup 创建路由前缀组,它能统一添加公共路径前缀并链式配置中间件与授权策略;其次可封装委托实现模块化、用元数据语义化分组、mapfallback 处理嵌套路由、source generator 自动生成路由。

如果您在使用 C# Minimal API 时发现大量端点路由分散定义、缺乏逻辑分组,导致代码可维护性下降,则可能是由于未对相关路由进行结构化归类。以下是组织 Minimal API 路由的多种方法:
一、使用 MapGroup 扩展方法创建路由前缀组
MapGroup 是 Minimal API 提供的原生机制,用于为一组端点统一添加公共路径前缀,并支持链式配置中间件与授权策略。它不创建新服务实例,仅在路由匹配阶段生效。
1、在 Program.cs 中调用 builder.MapGroup("/api/products") 创建以 /api/products 为根路径的路由组。
2、在该组上调用 AddEndpointFilter、RequireAuthorization 等扩展方法,为组内所有端点统一应用横切逻辑。
3、在组内使用 MapGet、MapPost 等方法注册具体端点,其路径将自动拼接为 /api/products/list、/api/products/{id} 等形式。
二、通过委托封装路由注册逻辑实现模块化
将特定业务域的路由注册逻辑提取为独立的 Action
1、定义静态方法 public static void MapOrderEndpoints(this IEndpointRouteBuilder endpoints) { ... }。
2、在该方法内部调用 endpoints.MapGroup("/orders").MapGet(...).MapPost(...) 等完成完整路由注册。
3、在 Program.cs 中直接调用 builder.MapOrderEndpoints() 即可挂载整套订单路由。
三、利用 RouteHandlerBuilder 的 WithName 和 WithMetadata 实现语义化分组标识
虽不改变路径结构,但可通过元数据标记路由归属,配合第三方工具(如 Swagger 文档生成器)实现逻辑分组呈现,提升 API 文档可读性。
1、对每个 MapGet 或 MapPost 调用后链式调用 WithName("Products_GetAll") 显式命名端点。
2、调用 WithMetadata(new RouteGroupMetadata("Products")) 附加自定义分组标识类型。
3、编写 IEndpointConventionBuilder 扩展方法,批量扫描并为具有相同 RouteGroupMetadata 的端点注入统一 Tags 或 Summary。
四、结合 RouteHandlerBuilder.MapFallback 实现嵌套路由捕获
当需要处理动态层级路径(如 /api/v1/users/123/settings/theme)且末端段数不确定时,可借助 MapFallback 捕获剩余路径片段,再交由中心化处理器解析。
1、调用 builder.MapGroup("/api/v{version:apiVersion}").MapFallback((context) => { ... })。
2、在委托中使用 context.Request.RouteValues["__remainingPath"] 获取未匹配部分。
3、手动分割 __remainingPath 字符串,依据第一段(如 "users")分发至对应领域处理器,实现伪嵌套路由分组。
五、基于约定的目录结构 + Source Generator 自动生成路由组
通过文件系统目录层级映射到路由前缀,并利用 Source Generator 在编译期扫描 [RouteGroup] 特性标记的静态类,生成 MapGroup 调用代码,消除运行时反射开销。
1、创建 /Endpoints/Products/GetAll.cs 文件,在其中定义标记 [RouteGroup("products")] 的 partial class ProductsEndpoints。
2、Source Generator 解析该特性及内部 MapGet 方法签名,生成 builder.MapGroup("/products").MapGet(...).WithName(...) 调用代码。
3、生成的代码写入 .g.cs 文件,被编译器自动包含,无需手动维护 Program.cs 中的路由注册语句。











