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

運行效果如下:

run

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

通過擴展方法 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 (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),備注來意,邀請進群

masa_stack_tech_ops.png

​ ------ END ------

作者簡介

馬躍:MASA技術團隊成員。


免責聲明!

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



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