.NET 6.0 Minimal API 介紹
前言
Minimal API是.NET 6中新增的模板,借助C# 10的一些特性以最少的代碼運(yùn)行一個(gè)Web服務(wù)。本文脫離VS通過VS Code,完成一個(gè)簡(jiǎn)單的Minimal Api項(xiàng)目的開發(fā)
創(chuàng)建項(xiàng)目
隨便新建一個(gè)文件夾,用來管理我們的項(xiàng)目文件,文件夾內(nèi)啟動(dòng)命令行,通過dotnet new web創(chuàng)建項(xiàng)目。

還是一堆文件, 什么時(shí)候一個(gè)Program.cs文件就能跑起一個(gè)Web項(xiàng)目沒準(zhǔn)哪天也可以了
運(yùn)行項(xiàng)目
項(xiàng)目目錄下執(zhí)行dotnet run,運(yùn)行項(xiàng)目。

嘗試玩點(diǎn)花的用網(wǎng)頁版VS Code (https://vscode.dev/)運(yùn)行項(xiàng)目,不過并沒有我想象中那么強(qiáng),還不支持。

Coding
builder實(shí)例提供了Services屬性,可以完成原本Startup類ConfigureServices方法中注冊(cè)服務(wù)的工作,Configure方法的一些Use操作則通過app來完成。
builder.Services.AddMemoryCache();
//todo
app.UseStaticFiles();
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", $"{builder.Environment.ApplicationName} v1"));
}MapGet變種
通過Build出來的app實(shí)例的MapGet方法實(shí)現(xiàn)路由的映射。
app.MapGet("/",?()?=>?"Hello?World!");
//app.Map("/",[HttpGet]?()?=>?"Hello?World!");
//app.MapMethods("/",?new?List()?{?HttpMethod.Get.ToString()?},?()?=>?"Hello?World!");
可以看到通過Delegate的方式可以直接在Delegate前加上對(duì)應(yīng)的特性。async關(guān)鍵字同樣可以直接標(biāo)記在Delegate前。
路由映射感覺還差點(diǎn)意思。不能像其它語言框架一樣進(jìn)行不同版本的管理,如:
var?api?=?app.Part("v1",middleware);
api.MapGet("",?()?=>{?return?"";?});
Application
代碼內(nèi)直接修改應(yīng)用程序配置,如修改監(jiān)聽端口
app.Urls.Add("http://localhost:3000");
//app.Urls.Add("http://localhost:4000");
//app.Run();
app.Run("http://localhost:4000");
優(yōu)先級(jí) app.Run > app.Urls.Add > launchSettings
Dependency Injection
Minimal API中無法使用構(gòu)造函數(shù)注入,可以通過參數(shù)方式注入,可以忽略掉FromServices特性的標(biāo)記。

Context
一些Http請(qǐng)求的上下文信息也可以通過參數(shù)直接指定,方法體內(nèi)直接使用,代替MVC中的Request等。如:
HttpContextHttpRequestHttpResponseClaimsPrincipalCancellationToken
app.MapGet("/context",?(HttpContext?httpContext)?=>?new?
{
????Data?=?httpContext.Connection.Id
});
更多類型參考:github
Responses
通過靜態(tài)類Results返回標(biāo)準(zhǔn)的相應(yīng)類型,實(shí)現(xiàn)和ControllerBase提供對(duì)應(yīng)方法相同的效果。
app.MapGet("/ok/{id}",?(int?id)?=>
{
????return?Results.Ok($"ok:{id}");
});
Link Generation
通過擴(kuò)展方法WithXXX等可以對(duì)路由進(jìn)行一些配置,如通過WithName指定名稱,再通過LinkGenerator生產(chǎn)對(duì)應(yīng)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擴(kuò)展方法外,還提供了AuthorizationEndpointConvention相關(guān)擴(kuò)展方法RequireAuthorization、AllowAnonymous代替MVC模式中的相關(guān)特性(特性也還可以用只是多了一個(gè)支持方式)。
本文只列出Minimal API的一些簡(jiǎn)單用法,集成Swagger等用法內(nèi)容參考:https://minimal-apis.github.io/hello-minimal/
接口的返回狀態(tài)碼和類型等可以通過擴(kuò)展方法Produces說明,如:Produces
Code Format
Minimal API上面示例存在的問題是Program文件中會(huì)有太多的編碼,所有路由的映射和響應(yīng)都在一起,雖然可以通過如下方式使用靜態(tài)方法抽離響應(yīng)方法,但所有的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完成代碼封裝。
詳細(xì)用法參考MASA.EShop

轉(zhuǎn)自:Stacking
鏈接:cnblogs.com/Stacking/p/minimal_api.html
