.Net Minimal APIs 介紹


Minimal APIs是.Net 6中新增的模板,借助C# 10的一些特性以最少的代碼運行一個Web服務。本文脫離VS通過VS Code,完成一個簡單的Minimal Api項目的開發。

創建項目

新建一個文件夾,用來管理我們的項目文件,文件夾內啟動命令行,通過`dotnet new web`創建項目。

 還是一堆文件,什么時候一個Program.cs文件就能跑起一個Web項目沒准哪天也可以了

運行項目

項目目錄下執行`dotnet run`,運行項目。

嘗試玩點花的用網頁版VS Code (https://vscode.dev/)運行項目,不過並沒有我想象中那么強,還不支持。

 Coding

builder實例提供了Services屬性,可以完成原本Startup類ConfigureServices方法中注冊服務的工作,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")); }

Map

builder.Build()返回的 app 實例提供了 Map、Methods、MapXXX 方法實現 HttpMethod 路由的映射。 這里只以 Get 請求為例。Map 和 MapMethods 方法提供不同的特性和參數可以代替 MapGet 方法。

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

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

可以看到通過Delegate的方式可以直接在Delegate前加上對應的特性。async關鍵字同樣可以直接標記在Delegate前。

路由映射感覺還差點意思。不能像其它語言框架一樣進行不同版本的管理,如:

var api = app.Part("v1",middleware);
api.MapGet("", () =>{ return ""; });

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}");
});

通過擴展方法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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM