一、前言
现在已经进入了微服务的开发时代了,在这个时代,如果有人问你什么是微服务,你说不知道,就有点太丢人了,别人会有异样的眼光看你,俗话说:唾液淹死人。没办法,我们只能去学习新的东西。一提到微服务,有一个绕不过的话题就是作为微服务的载体,WebAPI是离不开的。但是我们今天不讲WebAPI是什么,如何开发API,以及如何开发Restfull风格的API,我们聊另外一个话题,如何配置Swagger,让其支持多版本,并且支持参数、方法的注释说明。
为什么我们会说这呢,因为,我们要开发API,就会涉及到别人如何使用你的API,相应的使用文档就少不了,当时当我们有了Swagger,就不一样了。Swagger会为我们提供这个文档的功能。
我们今天开发的环境是:
操作系统:Windows 10 Professional
开发工具:Visual Studio 2022
开发语言:C#
开发平台:Asp.Net Core Web API 6.0。
平台类型:跨平台。
二、我们开始配置Swagger,让其支持多版本和注释。
在我们开始配置之前,先有一个直观的感受,我直接上一个截图。先来第一张截图,概况展示:
再来一张,接口内部详情的:
1、我们先设置一个版本信息的工具类,这个工具类可以放在单独的类库项目中,也可以放在 WebAPI 当前的项目中
/// <summary>
/// 该类型定义了 WebAPI 版本的信息。
/// </summary>
public static class ApiVersionInfo
{
/// <summary>
/// 初始化默认值。
/// </summary>
static ApiVersionInfo()
{
V1 = string.Empty;
V2 = string.Empty;
V3 = string.Empty;
V4 = string.Empty;
}
/// <summary>
/// 获取或者设置 V1 版本。
/// </summary>
public static string V1;
/// <summary>
/// 获取或者设置 V2 版本。
/// </summary>
public static string V2;
/// <summary>
/// 获取或者设置 V3 版本。
/// </summary>
public static string V3;
/// <summary>
/// 获取或者设置 V4 版本。
/// </summary>
public static string V4;
}
2、我们在 Program 里面配置 Swagger ,具体分为两个部分。
using PatrickLiu.Net6.WebApiDetails.Extensions;
using System.Reflection;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
#region 自定义配置Swagger
builder.Services.AddSwaggerGen(c =>
{
foreach (FieldInfo field in typeof(ApiVersionInfo).GetFields())
{
c.SwaggerDoc(field.Name, new Microsoft.OpenApi.Models.OpenApiInfo()
{
Title = $"{field.Name}:这里是 PatrickLiu 教育",
Version = field.Name,
Description = $"当前的 ASP.Net Core Web API {field.Name} 版本"
});
}
#region 增加api读取注释
//获取应用程序所在目录(绝对不受工作目录影响,建议采用此方法获取路径)
string? basePath = Path.GetDirectoryName(typeof(Program).Assembly.Location);
if (!string.IsNullOrEmpty(basePath) && !string.IsNullOrWhiteSpace(basePath))
{
string xmlPath = Path.Combine(basePath, "PatrickLiu.Net6.WebApiDetails.xml");
c.IncludeXmlComments(xmlPath);
}
#endregion
});
#endregion
#region 日志扩展
//builder.Logging.AddLog4Net("Config/log4net.config");
builder.Services.AddLogging(builder =>
{
builder.AddLog4Net("Config/log4net.config");
});
#endregion
var app = builder.Build();
#region Swagger 具体的配置
app.UseSwagger();
app.UseSwaggerUI(c =>
{
foreach (FieldInfo field in typeof(ApiVersionInfo).GetFields())
{
c.SwaggerEndpoint($"/swagger/{field.Name}/swagger.json", $"{field.Name}");
}
});
#endregion
app.UseAuthorization();
app.MapControllers();
app.Run();
3、我们建立我们自己的 APIController ,为每个 Controller 增加 [ApiExplorerSettings(GroupName = nameof(ApiVersionInfo.版本号)) ],我就创建了2个Controller。
/// <summary>
/// 订单的服务控制器。
/// </summary>
[Route("api/[controller]/[action]")]
[ApiController]
[ApiExplorerSettings(GroupName =nameof(ApiVersionInfo.V1))]
public class OrdersController : ControllerBase
{
/// <summary>
/// 获取数据列表。
/// </summary>
/// <returns></returns>
[HttpGet]
[Route("GetAll")]
public IEnumerable<string> Get()
{
return new string[] { "value1", "value2" };
}
/// <summary>
/// 获取主键所对应的数据。
/// </summary>
/// <param name="id">查询的主键。</param>
/// <returns></returns>
[HttpGet("{id}")]
public string Get(int id)
{
return "value";
}
/// <summary>
/// 增加数据。
/// </summary>
/// <param name="value">参数</param>
[HttpPost]
public void Post([FromBody] string value)
{
}
/// <summary>
/// 修改数据。
/// </summary>
/// <param name="id">查询主键。</param>
/// <param name="value">要修改的值。</param>
[HttpPut("{id}")]
public void Put(int id, [FromBody] string value)
{
}
/// <summary>
/// 删除数据。
/// </summary>
/// <param name="id">要删除的主键。</param>
[HttpDelete("{id}")]
public void Delete(int id)
{
}
}
/// <summary>
///
/// </summary>
[Route("v2/api/[controller]")]
[ApiController]
[ApiExplorerSettings(GroupName = nameof(ApiVersionInfo.V2))]
public class OrdersV2Controller : ControllerBase
{
/// <summary>
/// 获取数据列表。
/// </summary>
/// <returns></returns>
[HttpGet]
public IEnumerable<string> Get()
{
return new string[] { "value1", "value2" };
}
/// <summary>
/// 获取主键所对应的数据。
/// </summary>
/// <param name="id">查询的主键。</param>
/// <returns></returns>
[HttpGet("{id}")]
public string Get(int id)
{
return "value";
}
/// <summary>
/// 增加数据。
/// </summary>
/// <param name="value">参数</param>
[HttpPost]
public void Post([FromBody] string value)
{
}
/// <summary>
/// 修改数据。
/// </summary>
/// <param name="id">查询主键。</param>
/// <param name="value">要修改的值。</param>
[HttpPut("{id}")]
public void Put(int id, [FromBody] string value)
{
}
/// <summary>
/// 删除数据。
/// </summary>
/// <param name="id">要删除的主键。</param>
[HttpDelete("{id}")]
public void Delete(int id)
{
}
/// <summary>
/// 增加一个人。
/// </summary>
/// <param name="person">要增加的人</param>
/// <param name="id">主键值。</param>
/// <param name="name">姓名。</param>
/// <param name="sex">性别</param>
/// <param name="address">地址。</param>
[HttpPost]
[Route("PutData")]
public void PutData(SinglePerson person,int id,string name,bool sex,string address)
{
}
}
4、运行起来,看看效果吧。
三、结束语
当我们的WebAPI有了新版本,我们也不用怕了,只要按我的设置,就可以灵活应付。不负苍天,继续努力。