.NET7 Preview4 之OpenAPI swagger改进
Posted teayear
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了.NET7 Preview4 之OpenAPI swagger改进相关的知识,希望对你有一定的参考价值。
在MiniAPI系列中,《.NET6之MiniAPI(十八):OpenAPI swagger》介绍了swagger在MiniAPI框架中的使用,当时留下很多不足,随着.NET7 Preview4的推出,这方面得到了很大的改进,我还是使用“十八”这篇文章的案例。
如果想参看原来文章,见下面引用:
此次对OpenAPI的提升主要是通过命名空间Microsoft.AspNetCore.OpenApi带来的。
新建API项目,选用minimal api模板,并带有OpenAPI,同时在Nuget升级Swashbuckle.AspNetCore为6.3.1以后的版本,核心代码如下:
using Microsoft.AspNetCore.Http.HttpResults;
using Microsoft.AspNetCore.OpenApi;
using Microsoft.OpenApi.Models;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen(c =>
c.SwaggerDoc("v1",
new OpenApiInfo
Title = "MiniAPI7_new04-V1",
Version = "v1"
);
//添加授权
var schemeName = "Bearer";
c.AddSecurityDefinition(schemeName, new OpenApiSecurityScheme
In = ParameterLocation.Header,
Description = "请输入不带有Bearer的Token",
Name = "Authorization",
Type = SecuritySchemeType.Http,
Scheme = schemeName.ToLowerInvariant(),
BearerFormat = "JWT"
);
c.AddSecurityRequirement(new OpenApiSecurityRequirement
new OpenApiSecurityScheme
Reference = new OpenApiReference
Type = ReferenceType.SecurityScheme,
Id = schemeName
,
new string[0]
);
);
var app = builder.Build();
if (app.Environment.IsDevelopment())
app.UseSwagger();
app.UseSwaggerUI(c =>
c.EnablePersistAuthorization();
);
//增
app.MapPost("/test", Results<Ok<Data>, NotFound> (Data data) =>
if (data != null)
data.ID = 101;
return TypedResults.Ok(data);
else
return TypedResults.NotFound();
)
.WithTags("all test")
.WithOpenApi(operation =>
operation.Description = "这是一个神密的功能,用来实现添加";
operation.Summary = "添加Data";
operation.Parameters.Clear();
operation.RequestBody = new OpenApiRequestBody
Description = "添加的数据实体",
Required = true,
Content = new Dictionary<string, OpenApiMediaType>
"application/json", new OpenApiMediaType
Schema = new OpenApiSchema
Type = "object",
Properties = new Dictionary<string, OpenApiSchema>
"ID",new OpenApiSchema Type="integer" ,
"Name",new OpenApiSchema Type="string" ,
"Token",new OpenApiSchema Type="string"
,
,
,
;
return operation;
);
//删
app.MapDelete("/test/id", Results<Ok, NotFound> (int? id) =>
if (id.HasValue)
return TypedResults.Ok();
else
return TypedResults.NotFound();
)
.WithTags("all test")
.WithOpenApi(operation =>
operation.Description = "这是一个神密的功能,用来实现删除";
operation.Summary = "按编号删除";
operation.Parameters[0].Description = "编号";
operation.Parameters[0].AllowEmptyValue = true;
return operation;
);
//改
app.MapPut("/test", (Data data) =>
)
.WithTags("all test")
.WithOpenApi(operation =>
operation.Description = "这是一个神密的功能,用来实现修改";
operation.Summary = "修改Data";
operation.Parameters.Clear();
return operation;
);
//查
app.MapGet("/test/id", Results<Ok<Data>, NotFound> (HttpRequest request, int? id) =>
if (id.HasValue)
return TypedResults.Ok(new Data() ID = id.Value, Name = "测试", Token = request.Headers["Authorization"] );
else
return TypedResults.NotFound();
)
.WithTags("all test")
.WithOpenApi(operation =>
operation.Description = "这是一个神密的功能,用来实现查询";
operation.Summary = "按编号查询";
operation.Parameters[0].Description = "编号";
operation.Parameters[0].AllowEmptyValue = true;
return operation;
);
app.Run();
/// <summary>
/// 提交数据
/// </summary>
class Data
/// <summary>
/// 编号
/// </summary>
public int ID get; set;
/// <summary>
/// 名称
/// </summary>
public string? Name get; set;
/// <summary>
/// Token
/// </summary>
public string? Token get; set;
当年在做go时,很羡慕它的时间有微秒,纳秒,在做性能优化时,能很小颗粒度的查看引入方法执行的时间,当时.net的DateTime只有毫秒(虽然也有别的办法获取)。现在,在最新的.NET7 Preview4中,DateTime也有微秒和纳秒了,倍感亲切。
纳秒在百位上,没有十位和个位,但这也说明.NET在进化,向高性能进化,在乎微秒和百位纳秒了(哈哈)。
下面是引入这两个时间单位的实现:
namespace System
public struct DateTime
public DateTime(int year, int month, int day, int hour, int minute, int second, int millisecond, int microsecond);
public DateTime(int year, int month, int day, int hour, int minute, int second, int millisecond, int microsecond, System.DateTimeKind kind);
public DateTime(int year, int month, int day, int hour, int minute, int second, int millisecond, int microsecond, System.Globalization.Calendar calendar);
public int Microsecond get;
public int Nanosecond get;
public DateTime AddMicroseconds(double value);
public struct DateTimeOffset
public DateTimeOffset(int year, int month, int day, int hour, int minute, int second, int millisecond, int microsecond, System.TimeSpan offset);
public DateTimeOffset(int year, int month, int day, int hour, int minute, int second, int millisecond, int microsecond, System.TimeSpan offset, System.Globalization.Calendar calendar);
public int Microsecond get;
public int Nanosecond get;
public DateTimeOffset AddMicroseconds(double microseconds);
public struct TimeSpan
public const long TicksPerMicrosecond = 10L;
public const long NanosecondsPerTick = 100L;
public TimeSpan(int days, int hours, int minutes, int seconds, int milliseconds, int microseconds);
public int Microseconds get;
public int Nanoseconds get;
public double TotalMicroseconds get;
public double TotalNanoseconds get;
public static TimeSpan FromMicroseconds(double microseconds);
public struct TimeOnly
public TimeOnly(int day, int hour, int minute, int second, int millisecond, int microsecond);
public int Microsecond get;
public int Nanosecond get;
.NET Preview5中,给MiniAPI带来了一个参数绑定的功能,看到这个功能,我一下子就开心了,因为它提供了一个把松散的传入数据或注入功能耦合在一起的能力,并且可以根据自己的需求自由组合,结合上原来的Fromxxx(Name=“”)]使用,尤其和谐。
看一下下面的例子,如果每个请求都带有X-UUID,可以直接放在父类里,这样的组合是不是更加灵活多变。
using Microsoft.AspNetCore.Mvc;
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
app.MapGet("/test", ([AsParameters] Order order) =>
order.Logger?.LogInformation(order.UUID);
);
app.Run();
class Header
[FromHeader(Name = "X-UUID")]
public string? UUID get; set;
class Order : Header
[FromQuery(Name = "no")]
public int OrderNo get; set;
public ILogger<Order>? Logger get; set;
绑定的参数,不只是class,还可以是其他自定义类型。
结构
struct Order
[FromHeader(Name = "X-UUID")]
public string? UUID get; set;
[FromQuery(Name = "no")]
public int OrderNo get; set;
public ILogger<Order>? Logger get; set;
记录
record Order
[FromHeader(Name = "X-UUID")]
public string? UUID get; set;
[FromQuery(Name = "no")]
public int OrderNo get; set;
public ILogger<Order>? Logger get; set;
结构记录
record struct Order
[FromHeader(Name = "X-UUID")]
public string? UUID get; set;
[FromQuery(Name = "no")]
public int OrderNo get; set;
public ILogger<Order>? Logger get; set;
虽然这只是.NET的一小步,但给开发人员带了一大步,使整个API开发体验得到了,特别对数据接收体验提升了一大截。
以上是关于.NET7 Preview4 之OpenAPI swagger改进的主要内容,如果未能解决你的问题,请参考以下文章
.NET7 Preview4 之OpenAPI swagger改进
MiniAPI:.NET7 Preview4之MiniAPI更新总览
.NET7 Preview4:重构的返回值TypedResults