我在写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进行分组的要求,还是使用原生的还是不会清晰,原因是:

  1. 要对 MapGroup 进行赋值,比如说 var accountGroup = app.MapGroup("Account"),每个组都要想个名字。

  2. 不能清楚自己的边界,比如说 写代码时,有可能出现插队的情况,本来 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的更多相关文章

  1. .Net Minimal Api 介绍

    Minimal API是.Net 6中新增的模板,借助C# 10的一些特性以最少的代码运行一个Web服务.本文脱离VS通过VS Code,完成一个简单的Minimal Api项目的开发. 创建项目 随 ...

  2. ASP.NET Core 6 Minimal API的模拟实现

    Minimal API仅仅是在基于IHost/IHostBuilder的服务承载系统上作了小小的封装而已,它利用WebApplication和WebApplicationBuilder这两个类型提供了 ...

  3. 【.NET 6】使用.NET 6开发minimal api以及依赖注入的实现、VS2022热重载和自动反编译功能的演示

    前言: .net 6 LTS版本发布已经有若干天了.此处做一个关于使用.net 6 开发精简版webapi(minimal api)的入门教程,以及VS2022 上面的两个强大的新技能(热重载.代码自 ...

  4. 简单聊下.NET6 Minimal API的使用方式

    前言 随着.Net6的发布,微软也改进了对之前ASP.NET Core构建方式,使用了新的Minimal API模式.之前默认的方式是需要在Startup中注册IOC和中间件相关,但是在Minimal ...

  5. 【.NET6】gRPC服务端和客户端开发案例,以及minimal API服务、gRPC服务和传统webapi服务的访问效率大对决

    前言:随着.Net6的发布,Minimal API成了当下受人追捧的角儿.而这之前,程序之间通信效率的王者也许可以算得上是gRPC了.那么以下咱们先通过开发一个gRPC服务的教程,然后顺势而为,再接着 ...

  6. 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 ...

  7. EF框架step by step(9)—Code First Fluent API

    在上一篇中,讲述了用数据特性的方式来标识实体与数据表之间的映射关系,在Code First方法中,还可以通过Fluent API的方式来处理实体与数据表之间的映射关系. 要使用Fluent API必须 ...

  8. 【EF】EF框架 Code First Fluent API

    在Code First方法中,还可以通过Fluent API的方式来处理实体与数据表之间的映射关系. 要使用Fluent API必须在构造自定义的DbContext时,重写OnModelCreatin ...

  9. Code Walkthroughs Table API

    上级:https://www.cnblogs.com/hackerxiaoyon/p/12747387.html Table API Table api 有批量的api和流实时的api.通常很容易进行 ...

  10. .net core 2.0 Code First Fluent API配置

    A.net core 2.0新特性支持通过IEntityTypeConfiguration<>添加Code First配置到一个封装类. 新建目标框架为.NET Core类库 新建完了以后 ...

随机推荐

  1. 京东一面:如何在SpringBoot启动时执行特定代码?有哪些方式?

    引言 Spring Boot 提供了许多便捷的功能和特性,使得开发者可以更加轻松地构建强大.高效的应用程序.然而,在应用程序启动时执行一些初始化操作是至关重要的,它可以确保应用程序在启动后处于预期的状 ...

  2. CentOS 8 安装更新国内清华大学源手记【亲测成功】

    一直和各种OS打交道,仍觉得自己是小白,故深知小白们的困惑和蛋碎,特此将安装更新源的细节和步骤做了详细整理,供大家参考.红字是命令和提示,深灰色代码框中是源配置,本文采用了清华大学CentOS 8的源 ...

  3. 报表的 SQL 注入风险是什么意思?如何防范?

    啥是 SQL 注入风险? 数据库要执行 SQL 访问数据,数据库是个执行机构,它只会检查传来的 SQL 是不是合乎语法,而并不会关心这个语句是否会造成伤害(数据泄露或破坏).正因为只要符合语法规则就会 ...

  4. VScode 使用emmet

    背景 在很多的编辑场合,很多时候回出现很多逻辑性的问题.可能觉得html是一门没有逻辑的语言,实际上,它是有一定的思想编辑的.后来出现了emmet,这个不仅仅是一种快捷方式,同时也是一种思考方式. 解 ...

  5. T-SQL中执行存储过程与C#执行同样操作的比较

    1 exec sp_executesql N"UPDATE [dbo].[Courses] 2 SET [Title] = @0 3 WHERE (([CourseID] = @1) AND ...

  6. 《C# in depth》第6章C#6.0中的更改(十四)——表达式体

    表达式体成员是一种在C# 6及以上版本中引入的语法.它允许开发人员使用Lambda表达式来简化方法或属性的定义. 在使用表达式体成员时,可以将方法或属性的实现写在一个Lambda表达式中,然后直接返回 ...

  7. 基础 IO (Linux学习笔记)

    基础IO 1.重谈文件 空文件在磁盘也要占据空间 文件 = 内容 + 属性 文件操作 = 对文件内容+对属性 or 对文件内容加属性 标定一个文件,必须使用文件路径加文件名[唯一性] 如果没有指明对应 ...

  8. SnakeYaml反序列化分析

    前言 SnakeYaml是Java中解析yaml的库,而yaml是一种人类可读的数据序列化语言,通常用于编写配置文件等.yaml真是到哪都有啊. 环境搭建 <dependency> < ...

  9. 比Bloom Filter节省25%空间!Ribbon Filter在Lindorm中的应用

    简介: 本文研究了一种新的过滤器Ribbon Filter,并将其集成到Lindorm中 作者:箫苏 朝戈 正研 1 前言 Lindorm是一个低成本高吞吐的多模数据库,目前,Lindorm是阿里内部 ...

  10. Serverless 应用优化四则秘诀

    ​简介:Serverless 架构下,虽然我们更多精力是关注我们的业务代码,但是实际上对于一些配置和成本也是需要进行关注的,并且在必要的时候,还需要根据配置与成本进行对我们的 Serverless 应 ...