Intro
.NET 6 Preview 4 开始引入了 Minimal API 到如今的 RC1,Minimal API 也完善了许多并且修复了很多BUG,之前也写过文章介绍,可以参考:ASP.NET Core 6 Minimal API ,不过只是写了一个 Hello World, 最早还要 Using 现在默认启用了隐式命名空间可以不用在代码里写 using 了,今天就来用 Minimal API 来写一个简单的增删改查的 Todo API,一起来看下面的示例吧
Sample
下面的这个小示例,除了基本的增删改查 API 还包含了 swagger 的配置、 EF Core 的使用以及认证授权
示例代码如下:
var builder = WebApplication.CreateBuilder(args);
// 注册 DbContext
builder.Services.AddSqlite<TodoDbContext>(builder.Configuration.GetConnectionString("Todo"));
// 注册 swagger
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new() { Title = "MinimalTodoAPI", Version = "v1" });
});
// 注册认证授权
builder.Services.AddAuthentication(QueryAuthenticationDefaults.AuthenticationSchema)
.AddQuery();
builder.Services.AddAuthorization();
var app = builder.Build();
// 初始化数据库
using (var scope = app.Services.CreateScope())
{
await scope.ServiceProvider.GetRequiredService<TodoDbContext>()
.Database.EnsureCreatedAsync();
}
// 配置 HTTP 请求管道
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "MinimalTodoAPI v1"));
}
app.Map("/health", Results.Ok);
app.MapGet("/contextSample", (HttpContext context) =>
{
return Results.Ok(context.Request.Query);
}).ExcludeFromDescription(); // 从 swagger 中排除此 API
// Todo 的增删改查 API
app.MapGet("/api/todo", (TodoDbContext dbContext) => dbContext.TodoItems.AsNoTracking().ToArrayAsync());
app.MapPost("/api/todo", async (TodoItem item, TodoDbContext dbContext) =>
{
if(string.IsNullOrWhiteSpace(item?.Title))
{
return Results.BadRequest();
}
item.Id = 0;
item.CreatedAt = DateTime.UtcNow;
dbContext.TodoItems.Add(item);
await dbContext.SaveChangesAsync();
return Results.Created($"/api/todo/{item.Id}", item);
});
app.MapPut("/api/todo/{id}", async (int id, TodoItem item, TodoDbContext dbContext) =>
{
if(id <= 0 || string.IsNullOrWhiteSpace(item?.Title))
{
return Results.BadRequest();
}
var todo = await dbContext.TodoItems.FindAsync(id);
if(todo is null)
{
return Results.NotFound();
}
todo.Title = item.Title;
todo.Description = item.Description;
todo.Done = item.Done;
await dbContext.SaveChangesAsync();
return Results.Ok(todo);
});
// 认证授权
app.UseAuthentication();
app.UseAuthorization();
app.MapDelete("/api/todo/{id}", async (int id, TodoDbContext dbContext) =>
{
if (id <= 0)
{
return Results.BadRequest();
}
var todo = await dbContext.TodoItems.FindAsync(id);
if (todo is null)
{
return Results.NotFound();
}
dbContext.Remove(todo);
await dbContext.SaveChangesAsync();
return Results.Ok(todo);
}).RequireAuthorization();
app.Run();
上面示例注册 EF Core DbContext 的时候用的上次我们介绍的简化后的注册方式 EF Core 6 简化的数据库上下文注册
我们可以使用
MapGet/MapPost/MapPut/MapDelete 来限制请求方法,可以使用 Results 来方便的返回 API 结果, 类似于在 Controller 里调用 Ok/BadRequest/NotFound 等方法
swagger 界面:
swagger ui
我们来测试一下需要认证的 Delete API, 前面我们注册服务的时候使用了一个自定义的一个基于 query string 的认证方式以方便进行测试,下面我们来测试一下,首先需要调用 POST API 来创建一个 todo,然后调用 GET API 来确认一下 todo 创建成功了,之后就可以测试我们的 DELETE API 了
我这里使用之前开发的 dotnet-httpie(dotnet-HTTPie) 来进行测试,你也可以使用 Postman 或者别的工具来测试
首先执行下面的命令
http delete -v --schema=https :7229/api/todo/1
HTTP 请求响应信息如下:
DELETE /api/todo/1 HTTP/1.1
Host: localhost:7229
Schema: https
User-Agent: dotnet-HTTPie/0.1.1
HTTP/1.1 401 Unauthorized
Content-Length: 0
Date: Sun, 19 Sep 2021 15:59:19 GMT
Server: Kestrel
这里我们没有提供任何的认证相关的信息,所以 API 返回了 401
接着我们提供认证信息来测试一下,在 query string 中添加 userId 和 userName 信息,执行下面的命令
http delete -v --schema=https :7229/api/todo/1 userId==1 userName==test
HTTP 请求响应信息如下:
DELETE /api/todo/1?userId=1&userName=test HTTP/1.1
Host: localhost:7229
Schema: https
User-Agent: dotnet-HTTPie/0.1.1
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Date: Sun, 19 Sep 2021 16:04:29 GMT
Server: Kestrel
Transfer-Encoding: chunked
{"id":1,"title":"test","description":"test","done":false,"createdAt":"2021-09-19T15:57:31.3370653"}
可以看到此时返回了 200,已经删除成功了,不再是 401 了,我们也可以再调用一下 list API 来看一下是否真的被删除了,可以看到已经没有元素返回了
对于创建一个新 todo 的 POST API 也可以使用 dotnet-httpie 来方便的请求
More
对于简单的快速试错的 API 推荐使用 Minimal API 来实现,问题不大,但是比较复杂的应用个人还是推荐走 MVC/Web API 的形式,更为成熟,功能更全面,Minimal API 很多功能不支持或者支持的不太好,比如说 Minimal API 是不支持对 model 进行验证的,是没有 ModelState 的,即使 model 里声明了 Required 等验证,在 Minimal API 里也是不起作用的,也不支持 API-Version,另外对于 API 的分组支持也是比较弱的,要自己指定 tag 去分组,不如使用 Controller 简单方便
上面的源码可以在 Github 上获取
https://github.com/WeihanLi/SamplesInPractice/tree/master/net6sample/MinimalTodoAPI
对于 Minimal API 的使用,微软专门做了一个文档网站来介绍其使用,可以参考:
https://minimal-apis.github.io/
另外微软的大佬 David 在 Gist 上也有一篇关于 Minimal API 的总结,可以参考:
https://gist.github.com/davidfowl/ff1addd02d239d2d26f4648a06158727
References
- https://github.com/WeihanLi/SamplesInPractice/tree/master/net6sample/MinimalTodoAPI
- https://github.com/Minimal-APIs/minimal-apis.github.io
- https://minimal-apis.github.io/
- https://gist.github.com/davidfowl/ff1addd02d239d2d26f4648a06158727
- ASP.NET Core 6 Minimal API
- 使用 Minimal API 改造动态文件提供者
内容出处:,
声明:本网站所收集的部分公开资料来源于互联网,转载的目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。如果您发现网站上有侵犯您的知识产权的作品,请与我们取得联系,我们会及时修改或删除。文章链接:http://www.yixao.com/tech/29399.html