Introduction to Minimal APIs
Introduction to Minimal APIs
https://jdaniel1987.github.io/MinimalApis
这是一篇为您整理好的博客文章,已经根据原文内容进行了结构化处理,保留了代码示例和图文并茂的排版风格,您可以直接复制发布。
🚀 .NET 极简 API (Minimal APIs) 入门指南
随着现代 Web 应用程序的演进,开发者们一直在寻求一种能以更低复杂度、更高效率创建 API 的方法。这正是 .NET 极简 API (Minimal APIs) 发挥作用的地方。
极简 API 随 .NET 6 一同推出,它提供了一种轻量级的方式来构建 HTTP API,极大地减少了繁琐的设置,让开发者能够专注于应用程序的核心逻辑。
极简 API 减少了 ASP.NET Core 应用程序中通常需要的样板代码,简化了定义路由、处理请求和返回响应的过程。通过这种简单而强大的方法,极简 API 非常适合构建小型的、面向微服务的应用程序,以及大型系统的原型开发。
🌟 极简 API 的优势
- 简化的语法:极简 API 允许您用最少的语法定义路由和端点,减少了设置完整 ASP.NET Core 项目的开销。
- 更快的开发速度:编写和维护的代码更少,您可以更快地开发和部署 API,从而更容易地迭代和完善您的应用程序。
- 性能:由于其轻量级的特性,极简 API 可以提供更好的性能,特别是在速度和效率至关重要的场景中。
- 灵活性:极简 API 高度可定制,并且可以轻松与其他 ASP.NET Core 功能(如中间件、依赖注入等)集成。
- 可扩展性:虽然设计初衷是简化,但极简 API 仍然可以扩展以满足大型应用程序的需求,特别是与 Carter 等模块化模式结合使用时。
- 非常适合微服务:这种极简主义的方法与微服务架构非常契合,在微服务架构中,小型、可独立部署的服务是常态。
💻 使用示例
1. 设置一个极简 API
要开始使用极简 API,请创建一个新的 .NET Web API 项目,并直接在 Program.cs 文件中添加必要的路由定义。
以下是一个简单的示例:
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
app.MapGet("/api/greet", () => "Hello, world!");
app.Run();
注意:在这个例子中,我们定义了一个简单的 GET 端点,返回一句问候。请注意设置是多么简洁,无需控制器或额外的路由配置。
您可以使用所有现有的 HTTP 动词(Get, Post, Put, Patch, Delete)。
2. 向路由添加参数
极简 API 支持在路由定义中使用参数,这使得创建动态端点变得非常容易:
app.MapGet("/api/greet/{name}", (string name) => $"Hello, {name}!");
这个端点会根据名字向用户问好,展示了极简 API 如何轻松处理路由参数。
您还可以在参数上使用属性来提供额外的元数据、控制绑定行为或应用验证:
app.MapGet("/api/resource", ([FromQuery] string param) => {
return $"Query parameter: {param}";
});
ASP.NET Core 极简 API 中常用的属性:
[FromQuery]– 将参数绑定到查询字符串值。[FromRoute]– 将参数绑定到路由值。[FromBody]– 将参数绑定到请求体。[FromHeader]– 将参数绑定到 HTTP 请求头中的值。[FromForm]– 将参数绑定到表单数据。
3. 集成中间件 (可选)
极简 API 可以轻松与 ASP.NET Core 中间件集成,以向请求处理管道添加自定义逻辑。
例如,我们可以创建一个测量请求处理时间的中间件:
public class RequestTimingMiddleware
{
private readonly RequestDelegate _next;
public RequestTimingMiddleware(RequestDelegate next)
{
_next = next;
}
public async Task InvokeAsync(HttpContext context)
{
var stopwatch = Stopwatch.StartNew();
await _next(context);
stopwatch.Stop();
var elapsedTime = stopwatch.ElapsedMilliseconds;
context.Response.Headers.Add("X-Elapsed-Time", $"{elapsedTime}ms");
}
}
要在 Program.cs 的请求管道中注册并使用该中间件:
app.UseMiddleware<RequestTimingMiddleware>();
在此示例中,中间件测量处理每个请求所需的时间,并将该值作为
X-Elapsed-Time头添加到响应中。这对于调试或监控应用程序性能非常有用。通过利用中间件,您可以管理日志记录、身份验证等横切关注点,而不会使端点定义变得复杂。
4. 使用过滤器 (Filters)
过滤器用于处理验证、错误处理、日志记录和其他横切关注点。
app.MapPost("/users", async (User user) => {
// .................... logic
return Results.Created($"/users/{user.Id}", user);
})
.AddEndpointFilter(async (context, next) => {
var user = (User)context.Arguments[0];
if (string.IsNullOrWhiteSpace(user.Name) || !user.Email.Contains("@"))
{
return Results.BadRequest("Invalid user data");
}
return await next(context);
});
5. 依赖注入 (Dependency Injection)
在极简 API 中,注册在应用程序服务容器中的服务(使用 builder.Services.Add...)可以作为参数直接注入到端点处理程序中。
注册服务:
builder.Services.AddScoped<IMyService, MyService>();
在端点中注入:
app.MapGet("/greet", (IMyService service) => {
return service.GetGreeting();
});
6. 使用 OpenAPI 进行文档化
您可以使用 OpenAPI 自动生成详细的 API 文档。这通常通过 Swagger 等工具完成,它们会根据您的 API 结构生成一个交互式界面。
基础配置:
app.MapGet("/greet", () => "Hello, World!")
.WithName("Greet") // 为操作分配一个名称
.WithOpenApi(); // 自动记录此路由
(此处通常会显示 Swagger UI 界面,展示 GET /greet 接口的参数和响应)
高级配置示例:
对于更复杂的接口,您可以详细定义摘要、描述、标签和可能的响应状态码:
app.MapPost("api/AddGameConsole", (GameConsole gameConsole) => {
// .................................... Logic
return result.IsSuccess ?
Results.Created(gameConsole) :
Results.BadRequest(result.Error);
})
.WithOpenApi(operation => {
operation.Summary = "Adds a new games console";
operation.Description = "Creates a new games console entry in the system.";
return operation;
})
.WithName(nameof(AddGameConsoleModule))
.WithTags(nameof(GameConsole))
.ProducesValidationProblem()
.Produces(StatusCodes.Status201Created)
.Produces(StatusCodes.Status400BadRequest)
.Produces(StatusCodes.Status500InternalServerError);
(此处通常会显示 Swagger UI 界面,展示 POST /api/AddGameConsole 接口的请求体模型和多种响应状态)
📌 总结
极简 API 是 .NET 生态系统中的一个绝佳补充,它提供了一种直接且高效的方式来构建 API。无论您是开发小型微服务还是大型应用程序,极简 API 都提供了快速启动和运行项目所需的灵活性和简单性。
📚 扩展阅读:Carter
如果您发现您的 Program.cs 文件因端点映射而变得杂乱无章,请查看我的另一篇文章“Carter 入门”,其中解释了如何将极简 API 端点拆分到不同的文件中,以保持代码整洁。

浙公网安备 33010602011771号