Clear Code for Minimal API
我在写MinimalAPI的时候,发现不能最清晰的看到每个API,原因就是:WebAPI中不断增长逻辑处理过程
于是我在想如何简化API至一行,在一点一点想办法中,发现了简化DotNET Minimal API的方式。特此记录下来这个思路给需要帮助的人。我的灵感来源于 C# 11 功能 - 接口中的静态虚拟成员,通过静态虚拟成员清晰整个API。
这是我思路的最终结果:在 Program.cs 中设置中我们能通过一行代码,清晰的看到代码情况。
而无需指定平常不是很关心的处理过程和请求方式。
app.MapGroup("Connect", o =>
{
o.MapMethods<Authorize>("Authorize");
o.MapMethods<Authorize.Callback>("Authorize/Callback");
o.MapMethods<Token>("Token");
o.MapMethods<UserInfo>("UserInfo").RequireAuthorization(new AuthorizeAttribute()
{
AuthenticationSchemes = OpenIddictValidationAspNetCoreDefaults.AuthenticationScheme
});
o.MapMethods<Endsession>("Endsession");
});
app.MapGroup("Account", o =>
{
o.MapMethods<Login>("Login");
o.MapMethods<Externallogin>("Externallogin");
o.MapMethods<Externallogin.Callback>("Externallogin/Callback");
o.MapMethods<ConfirmationLogin>("ConfirmationLogin");
o.MapMethods<ForgotPassword>("ForgotPassword");
o.MapMethods<ResetPassword>("ResetPassword");
});
结果结束。
我们只需要简单的三步就可以做到这个事情,并且可以不用反射和其他的复杂过程。
第一步,我们需要创建(附带静态抽象函数的接口)IEndpointBase。
public interface IEndpointBase
{
public static abstract IEnumerable<string> HTTPMethods();
public static abstract Delegate Handler();
}
第二步,需要实现IEndpointBase。
public class Login : IEndpointBase
{
public record AccountLoginRequest
{
[JsonPropertyName("u"), Required]
public string UserName { get; set; } = default!;
[JsonPropertyName("p"), Required]
public string Password { get; set; } = default!;
[JsonPropertyName("r"), Required]
public string ReturnUrl { get; set; } = default!;
[FromQuery]
public bool UseCookies { get; set; }
}
public static Delegate Handler()
{
var callback = async ([FromBody] AccountLoginRequest request, [FromServices] SignInManager signInManager) =>
{
// Todo: returnUrl validate is success
var result = await signInManager.PasswordSignInAsync(request.UserName, request.Password, request.UseCookies, lockoutOnFailure: true);
return Results.Text(result.ToString());
};
return callback;
}
public static IEnumerable<string> HTTPMethods() => [HttpMethods.Post];
}
第三步:处理静态IEndpointBase,此时我们已经完成了这件事情。
public static RouteHandlerBuilder MapMethods<T>(this IEndpointRouteBuilder app, [StringSyntax("Route")] string pattern) where T : IEndpointBase
{
return app.MapMethods(pattern, T.HTTPMethods(), T.Handler());
}
更好代码方式清晰:我发现单纯的使用自己扩展好的 MapMethods 已经足够清晰了。
但如果有对API进行分组的要求,还是使用原生的还是不会清晰,原因是:
要对 MapGroup 进行赋值,比如说 var accountGroup = app.MapGroup("Account"),每个组都要想个名字。
不能清楚自己的边界,比如说 写代码时,有可能出现插队的情况,本来 accountGroup下面都是属于它的端点,结果不小心插进来一个别的。
于是简单的对MapGroup进行了扩展,最终结果在本文最上面。
public static void MapGroup(this IEndpointRouteBuilder endpoints, [StringSyntax("Route")] string prefix, Action<IEndpointRouteBuilder> action)
{
var group = endpoints.MapGroup(prefix);
action(group);
}
总结:通过这种方式,代码结构已经清晰多了。若是有议,可以在评论区联系我。
Clear Code for Minimal API的更多相关文章
- .Net Minimal Api 介绍
Minimal API是.Net 6中新增的模板,借助C# 10的一些特性以最少的代码运行一个Web服务.本文脱离VS通过VS Code,完成一个简单的Minimal Api项目的开发. 创建项目 随 ...
- ASP.NET Core 6 Minimal API的模拟实现
Minimal API仅仅是在基于IHost/IHostBuilder的服务承载系统上作了小小的封装而已,它利用WebApplication和WebApplicationBuilder这两个类型提供了 ...
- 【.NET 6】使用.NET 6开发minimal api以及依赖注入的实现、VS2022热重载和自动反编译功能的演示
前言: .net 6 LTS版本发布已经有若干天了.此处做一个关于使用.net 6 开发精简版webapi(minimal api)的入门教程,以及VS2022 上面的两个强大的新技能(热重载.代码自 ...
- 简单聊下.NET6 Minimal API的使用方式
前言 随着.Net6的发布,微软也改进了对之前ASP.NET Core构建方式,使用了新的Minimal API模式.之前默认的方式是需要在Startup中注册IOC和中间件相关,但是在Minimal ...
- 【.NET6】gRPC服务端和客户端开发案例,以及minimal API服务、gRPC服务和传统webapi服务的访问效率大对决
前言:随着.Net6的发布,Minimal API成了当下受人追捧的角儿.而这之前,程序之间通信效率的王者也许可以算得上是gRPC了.那么以下咱们先通过开发一个gRPC服务的教程,然后顺势而为,再接着 ...
- Code Your First API With Node.js and Express: Set Up the Server
How to Set Up an Express API Server in Node.js In the previous tutorial, we learned what the REST ar ...
- EF框架step by step(9)—Code First Fluent API
在上一篇中,讲述了用数据特性的方式来标识实体与数据表之间的映射关系,在Code First方法中,还可以通过Fluent API的方式来处理实体与数据表之间的映射关系. 要使用Fluent API必须 ...
- 【EF】EF框架 Code First Fluent API
在Code First方法中,还可以通过Fluent API的方式来处理实体与数据表之间的映射关系. 要使用Fluent API必须在构造自定义的DbContext时,重写OnModelCreatin ...
- Code Walkthroughs Table API
上级:https://www.cnblogs.com/hackerxiaoyon/p/12747387.html Table API Table api 有批量的api和流实时的api.通常很容易进行 ...
- .net core 2.0 Code First Fluent API配置
A.net core 2.0新特性支持通过IEntityTypeConfiguration<>添加Code First配置到一个封装类. 新建目标框架为.NET Core类库 新建完了以后 ...
随机推荐
- 京东一面:如何在SpringBoot启动时执行特定代码?有哪些方式?
引言 Spring Boot 提供了许多便捷的功能和特性,使得开发者可以更加轻松地构建强大.高效的应用程序.然而,在应用程序启动时执行一些初始化操作是至关重要的,它可以确保应用程序在启动后处于预期的状 ...
- CentOS 8 安装更新国内清华大学源手记【亲测成功】
一直和各种OS打交道,仍觉得自己是小白,故深知小白们的困惑和蛋碎,特此将安装更新源的细节和步骤做了详细整理,供大家参考.红字是命令和提示,深灰色代码框中是源配置,本文采用了清华大学CentOS 8的源 ...
- 报表的 SQL 注入风险是什么意思?如何防范?
啥是 SQL 注入风险? 数据库要执行 SQL 访问数据,数据库是个执行机构,它只会检查传来的 SQL 是不是合乎语法,而并不会关心这个语句是否会造成伤害(数据泄露或破坏).正因为只要符合语法规则就会 ...
- VScode 使用emmet
背景 在很多的编辑场合,很多时候回出现很多逻辑性的问题.可能觉得html是一门没有逻辑的语言,实际上,它是有一定的思想编辑的.后来出现了emmet,这个不仅仅是一种快捷方式,同时也是一种思考方式. 解 ...
- T-SQL中执行存储过程与C#执行同样操作的比较
1 exec sp_executesql N"UPDATE [dbo].[Courses] 2 SET [Title] = @0 3 WHERE (([CourseID] = @1) AND ...
- 《C# in depth》第6章C#6.0中的更改(十四)——表达式体
表达式体成员是一种在C# 6及以上版本中引入的语法.它允许开发人员使用Lambda表达式来简化方法或属性的定义. 在使用表达式体成员时,可以将方法或属性的实现写在一个Lambda表达式中,然后直接返回 ...
- 基础 IO (Linux学习笔记)
基础IO 1.重谈文件 空文件在磁盘也要占据空间 文件 = 内容 + 属性 文件操作 = 对文件内容+对属性 or 对文件内容加属性 标定一个文件,必须使用文件路径加文件名[唯一性] 如果没有指明对应 ...
- SnakeYaml反序列化分析
前言 SnakeYaml是Java中解析yaml的库,而yaml是一种人类可读的数据序列化语言,通常用于编写配置文件等.yaml真是到哪都有啊. 环境搭建 <dependency> < ...
- 比Bloom Filter节省25%空间!Ribbon Filter在Lindorm中的应用
简介: 本文研究了一种新的过滤器Ribbon Filter,并将其集成到Lindorm中 作者:箫苏 朝戈 正研 1 前言 Lindorm是一个低成本高吞吐的多模数据库,目前,Lindorm是阿里内部 ...
- Serverless 应用优化四则秘诀
简介:Serverless 架构下,虽然我们更多精力是关注我们的业务代码,但是实际上对于一些配置和成本也是需要进行关注的,并且在必要的时候,还需要根据配置与成本进行对我们的 Serverless 应 ...