方案选择
使用Web API时,了解其各种方法对开发人员来说可能是一项挑战。
Swagger也称为OpenAPI
(Open Application Programming Interface,开放应用编程接口),解决了为Web API生成有用文档和帮助页的问题。 它具有诸如交互式文档、客户端 SDK生成和API可发现性等优点。
Swagger/OpenAPI实现
- Swashbuckle.AspNetCore 实现
是一个开源项目,用于生成 ASP.NET Core Web API 的 Swagger 文档。
- NSwag 实现
是另一个用于生成 Swagger 文档并将 Swagger UI 或 ReDoc 集成到 ASP.NET Core Web API 中的开源项目。 此外,NSwag 还提供了为 API 生成 C# 和 TypeScript 客户端代码的方法。
什么是Swagger/OpenAPI
Swagger是一个与语言无关的规范,用于描述REST API。 Swagger项目已捐赠给OpenAPI计划,现在它被称为开放API。这两个名称可互换使用,但OpenAPI是首选。它允许计算机和人员了解服务的功能,而无需直接访问实现(源代码、网络访问、文档)。其中一个目标是尽量减少连接取消关联的服务所需的工作量。 另一个目标是减少准确记录服务所需的时间。
Swagger规范(swagger.json)
Swagger 流的核心是Swagger规范,默认情况下是名为
swagger.json
的文档。 它由 Swagger工具链(或其第三方实现)根据你的服务生成。它描述了 API 的功能以及使用 HTTP 对其进行访问的方式。 它驱动Swagger UI,并由工具链用来启用发现和客户端代码生成。
Swagger UI
Swagger UI提供了基于Web的UI,它使用生成的Swagger规范提供有关服务的信息。 Swashbuckle和NSwag均包含Swagger UI的嵌入式版本,因此可使用中间件注册调用将该嵌入式版本托管在ASP.NET Core 应用中。
背景知识
Swashbuckle 有三个主要组成部分:
Swashbuckle.AspNetCore.Swagger
将 SwaggerDocument 对象公开为 JSON 终结点的 Swagger 对象模型和中间件。
Swashbuckle.AspNetCore.SwaggerGen
从路由、控制器和模型直接生成 SwaggerDocument 对象的 Swagger 生成器。 它通常与 Swagger 终结点中间件结合,以自动公开 Swagger JSON。
Swashbuckle.AspNetCore.SwaggerUI
Swagger UI 工具的嵌入式版本。 它解释 Swagger JSON 以构建描述 Web API 功能的可自定义的丰富体验。 它包括针对公共方法的内置测试工具。
在NetCore 3中安装
Nuget 安装:Swashbuckle.AspNetCore
建议大于等于5.0版本
将Swagger生成器添加到Startup.ConfigureServices
方法中的服务集合中
NetCore 3.1中,原NetCore2.2中的
Info
已经升级为OpenApiInfo
。
基础版本
// Register the Swagger generator, defining 1 or more Swagger documents
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new OpenApiInfo { Title = "My API", Version = "v1" });
});
升级版本
主项目生成的地方记得勾选,生成XML,这个用于增强
// 注册Swagger生成器,定义一个和多个Swagger文档
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new OpenApiInfo
{
Version = "v1",
Title = "ToDo API",
Description = "A simple example ASP.NET Core Web API",
TermsOfService = new Uri("https://example.com/terms"),
Contact = new OpenApiContact
{
Name = "Shayne Boyer",
Email = string.Empty,
Url = new Uri("https://twitter.com/spboyer"),
},
License = new OpenApiLicense
{
Name = "Use under LICX",
Url = new Uri("https://example.com/license"),
}
});
// Set the comments path for the Swagger JSON and UI.
var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
c.IncludeXmlComments(xmlPath);
});
反射用于生成与 Web API 项目相匹配的 XML 文件名。 AppContext.BaseDirectory属性用于构造 XML 文件的路径。 一些 Swagger 功能(例如,输入参数的架构,或各自属性中的 HTTP 方法和响应代码)无需使用 XML 文档文件即可起作用。 对于大多数功能(即方法摘要以及参数说明和响应代码说明),必须使用 XML 文件。
在Startup.Configure
方法中,启用中间件为生成的JSON文档和Swagger UI提供服务
基础版本
// Enable middleware to serve generated Swagger as a JSON endpoint.
app.UseSwagger();
// Enable middleware to serve swagger-ui (HTML, JS, CSS, etc.),
// specifying the Swagger JSON endpoint.
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1");
});
升级版本
// Enable middleware to serve generated Swagger as a JSON endpoint.
app.UseSwagger();
// Enable middleware to serve swagger-ui (HTML, JS, CSS, etc.),
// specifying the Swagger JSON endpoint.
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1");
// 要在应用的根 (http://localhost:<port>/) 处提供 Swagger UI,请将 RoutePrefix 属性设置为空字符串:
//c.RoutePrefix = string.Empty;
// 要在应用的根 (http://localhost:<port>/) 处提供 Swagger UI,请将 RoutePrefix 属性设置为空字符串:
c.RoutePrefix = "doc";
});
晋级写法
接口增加描述注释
/// <summary>
/// 获取列表信息
/// </summary>
/// <returns></returns>
[HttpGet]
public IEnumerable<string> Get()
{
return new string[] { "value1", "value2" };
}
Swagger UI 显示上述代码的
<summary>
元素的内部文本
接口增加示范说明
/// <summary>
/// 获取列表信息
/// </summary>
/// <remarks>
/// 示例请求:
///
/// GET /Get
/// {
/// "id": 1,
/// "name": "Item1",
/// "isComplete": true
/// }
///
/// </remarks>
/// <returns></returns>
[HttpGet]
public IEnumerable<string> Get()
{
return new string[] { "value1", "value2" };
}
将
元素添加到Get操作方法文档。 它可以补充 元素中指定的信息,并提供更可靠的 Swagger UI。 元素内容可包含文本、JSON 或 XML。
数据模型增加注释
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
namespace TodoApi.Models
{
public class TodoItem
{
public long Id { get; set; }
[Required]
public string Name { get; set; }
[DefaultValue(false)]
public bool IsComplete { get; set; }
}
}
使用
System.ComponentModel.DataAnnotations
命名空间中的属性来标记模型,以帮助驱动Swagger UI组件。将[Required]
属性添加到TodoItem
类的Name
属性。
申明控制器响应内容类型
[Produces("application/json")]
[Route("api/[controller]")]
[ApiController]
public class TodoController : ControllerBase
{
private readonly TodoContext _context;
将
[Produces("application/json")]
属性添加到API控制器。 这样做的目的是声明控制器的操作支持application/json
的响应内容类型。
申明控制动作响应类型
/// <summary>
/// Creates a TodoItem.
/// </summary>
/// <remarks>
/// Sample request:
///
/// POST /Todo
/// {
/// "id": 1,
/// "name": "Item1",
/// "isComplete": true
/// }
///
/// </remarks>
/// <param name="item"></param>
/// <returns>A newly created TodoItem</returns>
/// <response code="201">Returns the newly created item</response>
/// <response code="400">If the item is null</response>
[HttpPost]
[ProducesResponseType(StatusCodes.Status201Created)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
public ActionResult<TodoItem> Create(TodoItem item)
{
_context.TodoItems.Add(item);
_context.SaveChanges();
return CreatedAtRoute("GetTodo", new { id = item.Id }, item);
}
使用Web API的开发人员最关心的问题是返回的内容,特别是响应类型和错误代码(如果不标准)。 在 XML注释和数据注释中表示响应类型和错误代码。
Create 操作成功后返回 HTTP 201 状态代码。 发布的请求正文为 NULL 时,将返回 HTTP 400 状态代码。 如果 Swagger UI 中没有提供合适的文档,那么使用者会缺少对这些预期结果的了解。
自定义私有品牌UI
public void Configure(IApplicationBuilder app)
{
app.UseStaticFiles();
API 文档页应代表品牌或主题。 将 Swashbuckle 组件标记为需要添加资源以提供静态文件,并构建文件夹结构以托管这些文件。
从 Swagger UI GitHub 存储库中获取 dist 文件夹的内容。 此文件夹包含 Swagger UI 页必需的资产。
创建 wwwroot/swagger/ui 文件夹,然后将 dist 文件夹的内容复制到其中 。
使用以下 CSS 在 wwwroot/swagger/ui 中创建 custom.css 文件,以自定义页面标题
.swagger-ui .topbar {
background-color: #000;
border-bottom: 3px solid #547f00;
}
引用其他 CSS 文件后,引用“ui”文件夹内 index.html 文件中的 custom.css :
<link href="https://fonts.googleapis.com/css?family=Open+Sans:400,700|Source+Code+Pro:300,600|Titillium+Web:400,600,700" rel="stylesheet">
<link rel="stylesheet" type="text/css" href="./swagger-ui.css">
<link rel="stylesheet" type="text/css" href="custom.css">
引用资源
Swagger/OpenAPI By Swashbuckle在NetCore 3.1中较NetCore 2.2使用的注意事项及入门