.Net Minimal API 介绍

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

创建项目

新建一个文件夹,用来管理我们的项目文件,文件夹内启动命令行,通过dotnet new web创建项目。

Minimal
├── obj
├── Properties
├── appsettings.Development.json
├── appsettings.json
├── Minimal.csproj
└── Program.cs

运行项目

项目目录下执行dotnet run,运行项目。

PS C:\Users\User01\Desktop\Minimal> dotnet run
正在生成...
info: Microsoft.Hosting.Lifetime[14]Now listening on: https://localhost:7221
info: Microsoft.Hosting.Lifetime[14]Now listening on: http://localhost:5252
info: Microsoft.Hosting.Lifetime[0]Application started. Press Ctrl+C to shut down.
info: Microsoft.Hosting.Lifetime[0]Hosting environment: Development
info: Microsoft.Hosting.Lifetime[0]Content root path: C:\Users\User01\Desktop\Minimal\

运行效果如下:

bb614e8cbef94c1781a9328c1e96ff47.png

Coding

builder 实例提供了 Services 属性,可以完成原本 Startup 类 ConfigureServices 方法中注册服务的工作,Configure 方法的一些 Use 操作则通过 app 来完成。

builder.Services.AddMemoryCache();app.UseStaticFiles();
if (app.Environment.IsDevelopment())
{app.UseSwagger();app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", $"{builder.Environment.ApplicationName} v1"));
}

Map

builder.Build()返回的 app 实例提供了 Map、Methods、MapXXX 方法实现 HttpMethod 路由的映射。这里只以 Get 请求为例。Map 和 MapMethods 方法提供不同的特性和参数可以代替 MapGet 方法。

app.MapGet("/", () => "Hello World!");
app.Map("/", [HttpGet] () => "Hello World!");

HttpGet 特性限定请求为 Get 请求,如果不指定则不限制请求方法,Get、Post 等方式可以请求改路由地址

app.MapMethods("/", new List<string>() { HttpMethod.Get.ToString() }, () => "Hello World!");

Application

代码内直接修改应用程序配置,如修改监听端口

app.Urls.Add("http://localhost:3000");
//app.Run();
app.Run("http://localhost:4000");

优先级 app.Run > app.Urls.Add > launchSettings

Dependency Injection

Minimal APIs 中无法使用构造函数注入,但可以通过参数方式注入并忽略 FromServices 特性。

app.MapGet("/info", (IWebHostEnvironment env) => new {Time = DateTimeOffset.UtcNow,env.EnvironmentName
});

Context

一些 Http 请求的上下文信息也可以通过参数直接指定,方法体内直接使用,代替 MVC 中的 Request 等。如:

  • HttpContext

  • HttpRequest

  • HttpResponse

  • ClaimsPrincipal

  • CancellationToken

app.MapGet("/context", (HttpContext httpContext) => new
{Data = httpContext.Connection.Id
});

更多类型参考:github

Responses

通过静态类 Results 返回标准的相应类型,实现和 ControllerBase 提供对应方法相同的效果。

app.MapGet("/ok/{id}", (int id) =>
{return Results.Ok($"ok:{id}");
});

Link Generation

通过扩展方法 WithXXX 等可以对路由进行一些配置,如通过 WithName 指定名称,再通过 LinkGenerator 生产对应 Uri,避免硬编码

app.MapGet("/context", (HttpContext httpContext) => new
{Data = httpContext.Connection.Id
}).WithName("hi");app.MapGet("hello", (LinkGenerator linker) =>$"The link to the hello route is {linker.GetPathByName("hi", values: null)}");

除了 WithXXX 等一些列 RoutingEndpointConvention 扩展方法外,还提供了 AuthorizationEndpointConvention 相关扩展方法 RequireAuthorization、AllowAnonymous 代替 MVC 模式中的相关特性(特性也还可以用只是多了一个支持方式)。

本文只列出 Minimal APIs 的一些简单用法,集成 Swagger 等用法内容参考:https://minimal-apis.github.io/hello-minimal/

接口的返回状态码和类型等可以通过扩展方法 Produces 说明,如:Produces<ResponseMode>(contentType:"application/xml"); ,但是接口备注貌似还不支持,我尝试了很多方式都不能正确显示。

Code Format

Minimal APIs 上面示例存在的问题是 Program 文件中会有太多的编码,所有路由的映射和响应都在一起,虽然可以通过如下方式使用静态方法抽离响应方法,但所有的 Route Map 还是列在一起,不能像 Controller 一样分离。

var handler = new HelloHandler();app.MapGet("/", handler.Hello);class HelloHandler
{public string Hello(){return "Hello World";}
}

可以借助开源框架 MASA.Contrib提供的 MASA.Contrib.Service.MinimalAPIs 完成代码封装。

详细用法参考 MASA.EShop

Program.cs

var builder = WebApplication.CreateBuilder(args);
var app = builder.Services.AddServices(builder);
app.Run();

HelloService.cs

public class HelloService : ServiceBase
{public HelloService(IServiceCollection services): base(services) =>App.MapGet("/api/v1/helloworld", ()=>"Hello World"));
}

我们正在行动,新的框架、新的生态

我们的目标是自由的易用的可塑性强的功能丰富的健壮的

所以我们借鉴Building blocks的设计理念,正在做一个新的框架MASA Framework,它有哪些特点呢?

  • 原生支持Dapr,且允许将Dapr替换成传统通信方式

  • 架构不限,单体应用、SOA、微服务都支持

  • 支持.Net原生框架,降低学习负担,除特定领域必须引入的概念,坚持不造新轮子

  • 丰富的生态支持,除了框架以外还有组件库、权限中心、配置中心、故障排查中心、报警中心等一系列产品

  • 核心代码库的单元测试覆盖率90%+

  • 开源、免费、社区驱动

  • 还有什么?我们在等你,一起来讨论

经过几个月的生产项目实践,已完成POC,目前正在把之前的积累重构到新的开源项目中

目前源码已开始同步到Github(文档站点在规划中,会慢慢完善起来):

MASA.BuildingBlocks

MASA.Contrib

MASA.Utils

MASA.EShop

BlazorComponent

MASA.Blazor

QQ群:7424099

微信群:加技术运营微信(MasaStackTechOps),备注来意,邀请进群

5f267cd7c82b1f06c803d90cd59e266f.png

                                                         ----- END ------

作者简介

马跃:MASA技术团队成员。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/293005.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

access 子窗体 鼠标滚动不工作_Python GUI项目实战(五)明细信息窗体的完善

前言上一节我们实现了明细窗体GUI的搭建&#xff0c;并且设置了查看、修改、添加三种不同的状态&#xff0c;框架搭建好了&#xff0c;内容并没有填充&#xff0c;本节我们继续完善这个项目&#xff0c;将学生信息填充进明细窗体中。一、填充当前学生信息1.需求目前我们已经实现…

弹性式分布数据集RDD——Pyspark基础 (二)

连载中&#xff1a;http://ihoge.cn/tags/pyspark/ title: 弹性式分布数据集RDD——Pyspark基础 &#xff08;二&#xff09; date: 2018-04-15 17:59:21 comments: true categories: - Spark tags: - pyspark RDD的内部运行方式 RDD不仅是一组不可变的JVM&#xff08;…

centos安装kvm

KVM的虚拟化需要硬件支持&#xff08;如Intel VT技术或者AMD V技术)。是基于硬件的完全虚拟化。而Xen早期则是基于软件模拟的Para-Virtualization&#xff0c;新版本则是基于硬件支持的完全虚拟化。但Xen本身有自己的进程调度器&#xff0c;存储管理模块等&#xff0c;所以代码…

http://blog.csdn.net/myan/article/details/1906

好奇点一下&#xff0c;有惊喜哦转载于:https://blog.51cto.com/bigmac/1275715

java.io.File.setExecutable(boolean executable) 方法来设置所有者对于此抽象路径名执行权限。

java.io.File.setExecutable(boolean executable) 方法来设置所有者对于此抽象路径名执行权限。 声明 以下是 java.io.File.setExecutable(boolean executable) 方法的声明&#xff1a; public boolean setExecutable(boolean executable) 参数 executable -- 设置访问权限为t…

导师都有哪些“秘密”没有告诉你?

全世界只有3.14 % 的人关注了爆炸吧知识真正决定人与人之间的差距的&#xff0c;其实是我们对事物的见识与内心的格局&#xff0c;见识的深浅决定人生的深浅&#xff0c;格局的大小决定了人生之路是宽是窄。今天给大家推荐几个有深度、有想法的公众号&#xff0c;希望能够给你带…

2021年全球知名开源项目大更新

下面简单回顾 2021 年一些带来较大变化和影响的项目更新信息。PHP 8.1.0 正式发布枚举&#xff0c;只读属性&#xff0c;First-class 可调用语法&#xff0c;新的初始化器&#xff0c;纯交集类型&#xff0c;Never 返回类型&#xff0c;Final 类常量&#xff0c;显式八进制数字…

C语言中extern的用法

C语言中的Extern用法 网上有很多帖子问C语言中Extern的用法&#xff0c;而且回答的详细程度各尽不同. 所以我就像写一篇博文来谈谈我对extern的看法&#xff0c;不一定十分恰当&#xff0c;只当大家共勉. 在具体到Extern的用法之前&#xff0c;有两个概念必须要能分清楚&#x…

由逻辑异或运算符而发现的PHP诡异运算符优先级

PHP的逻辑运算符中&#xff0c;xor表示逻辑异或 $a xor $b 结果 如果 $a 和 $b 有且仅有一个为 true&#xff0c;则返回 true&#xff1b;如果都是true 或 false&#xff0c;则返回false。 然而在测试xor运算符时&#xff0c;发现一点问题 错误情况1 <?php$a false xor tr…

mysql workbench_爬虫实例:玩转mysql(预备篇)

考完试的第一篇文章&#xff0c;开心~/1.什么是数据库/数据库是“按照数据结构来组织、存储和管理数据的仓库”。是一个长期存储在计算机内的、有组织的、可共享的、统一管理的大量数据的集合。数据库是以一定方式储存在一起、能与多个用户共享、具有尽可能小的冗余度、与应用程…

MongoDB基本命令的使用

成功启动MongoDB后&#xff0c;再打开一个命令行窗口输入mongo&#xff0c;就可以进行数据库的一些操作。 输入help可以看到基本操作命令&#xff1a; show dbs:显示数据库列表 show collections&#xff1a;显示当前数据库中的集合&#xff08;类似关系数据库中的表&#xff0…

RHEL6   Kickstart 无人值守安装

方法&#xff1a;FTPTFTPDHCPKickstartPXE从网络引导系统的做法可以不必从硬盘、软盘或者CD&#xff0d;ROM光盘&#xff0c;而是完全通过网络来引导一台计算机。这对于安装来说很方便&#xff0c;因为它意味着你可以坐在桌子旁边&#xff0c;不必走到机器那里插入CD&#xff0…

免安装免配置 还免费的Spark 集群 --Databrickes Spark Clould

http://ihoge.cn/2018/Databrickes.html 摘要&#xff1a;本文带你畅游Databrickes Spark Clould云服务。小白迅速上手大数据Spark开发环境&#xff0c;从此告别集群Bug的烦恼&#xff0c;彻底解放物理机负担让你随时随地想Run就Run&#xfffd;&#xfffd;。 目录&#xff…

C# 运算符的优先级和关联性

表1 显示了 C#运算符的优先级&#xff0c;其中顶部的运算符有最高的优先级&#xff08;即在包含多个运算符的表达式中&#xff0c;最先计算该运算符&#xff09;。除了运算符优先级&#xff0c;对于二元运算符&#xff0c;需要注意运算符是从左向右还是从右向左计算。除了少数运…

char *a 与char a[] 的区别和char** argv与char *argv[]区别

char *a 与char a[] 的区别 char *a "hello" 中的a是指向第一个字符‘a的一个指针 char a[20] "hello" 中数组名a也是执行数组第一个字符‘h’的指针 但二者并不相同&#xff1a; 看实例&#xff1a;把两个字符串相加&#xff1a; 结果&#xff1a; hell…

javascript设计模式之外观模式

/** 外观模式* 外观模式的主要意义在于简化类的接口&#xff0c;使其易于调用 */// 你常常在不经意中使用了外观模式&#xff0c;尤其类库中更多&#xff08;处理兼容性问题&#xff09; var addEvent function (el, ev, fn) {if (el.addEventListener) {el.addEventListener(…

arduino代码_纯纯小白开发arduino--我的调试经验

arduino 是什么我就不做介绍了。这里的小白并不是说我没有嵌入式开发经验而是说从来没有实际开发过arduino。虽然它在世界范围内都很流行&#xff0c;可是不知为何国内专业做嵌入式开发的人对它大多都嗤之以鼻。我对arduino的想法是&#xff1a;”不管黑猫白猫&#xff0c;抓到…

重要的ui组件——Behavior

v7包下的组件类似CoordinatorLayout推出也有一段时间了&#xff0c;大家使用的时候应该会体会到其中很多的便利&#xff0c;今天这篇文章带大家来了解一个比较重要的ui组件——Behavior。从字面意思上就可以看出它的作用&#xff0c;就是用来规定某些组件的行为的&#xff0c;那…

《转》CXF WebService 开发文档-目录索引

CXF WebService 开发文档-目录索引 上次介绍了Axis的WebService&#xff0c;现在我们来看看CXF是怎么完成WebService的。 Axis1 WebService 在线博文&#xff1a; http://www.cnblogs.com/hoojo/archive/2010/12/20/1911349.html Axis2 WebService 在线博文&#xff1a; http:/…