5

.Net Minimal Api 介绍

 2 years ago
source link: https://www.cnblogs.com/Stacking/p/minimal_api.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Minimal API是.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"));
}

MapGet变种

通过Build出来的app实例的MapGet方法实现路由的映射。

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

可以看到通过Delegate的方式可以直接在Delegate前加上对应的特性。async关键字同样可以直接标记在Delegate前。

路由映射感觉还差点意思。不能像其它语言框架一样进行不同版本的管理,如:

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

Application

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

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

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

Dependency Injection

Minimal API中无法使用构造函数注入,可以通过参数方式注入,可以忽略掉FromServices特性的标记。

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 API的一些简单用法,集成Swagger等用法内容参考:https://minimal-apis.github.io/hello-minimal/

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

Code Format

Minimal API上面示例存在的问题是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


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK