在 ASP.NET Core 6.0 中使用 Swagger/OpenAPI 丰富 Web API 文档

news/2024/11/14 12:59:49/

示例代码:https://download.csdn.net/download/hefeng_aspnet/89961435 

介绍

在选择或尝试与 API 集成之前,大多数开发人员都会查看其 API 文档。保持 API 文档更新以反映软件更改是一项挑战,需要时间和精力。对于 Web API,我们希望记录以下内容:

  • 授权类型(例如 API 密钥、承载令牌、授权码等)
  • 动作方法:端点、HTTP 方法、标头等。
  • 数据契约:服务端和客户端之间交换的数据的描述。我们可以显示每个参数的名称、类型、限制等。
  • 使用Web API帮助消费者快速启动的示例。

如果有一种标准化的方式来描述 Web API,让人类和计算机都可以生成、发现和理解其功能,而无需访问源代码,那就太好了。好消息,🎉 这个标准是存在的,称为OpenAPI 规范(OAS),最初基于Swagger 规范。

Web API documentation提供必要的信息(例如端点、数据契约等)来向我们的消费者描述我们的 Web API。但是,此外,我们可能希望为我们的源代码提供文档,以帮助开发人员改进和维护它。因此,aCode documentation将提供有关我们的项目、类、构造函数、方法等的信息。要从注释中自动生成代码文档,请先阅读 Wagner 和 Warren ( 2021 ) 的文章。

在本文中,我们将了解Web API documentation如何在 ASP .NET Core 中自动生成它,以及如何通过提供示例、不同版本的文档等来提供丰富的信息😉。

.NET Core 中的 OpenAPI

实际上,在 ASP .NET Core 项目中,我们使用特定的属性和 XML 注释将所有需要的信息(例如,HTTP 响应代码、信息消息等)直接定义到我们的源代码中。我们可以使用此信息自动生成描述我们 API 的 JSON 或 YAML 文档(或一组文档)。生成的文档称为OpenAPI definition,可用于:

  • API 文档生成工具(例如,Swagger UI、Redoc等)来呈现我们的 OpenAPI 定义(例如,作为网页)。
  • 代码生成工具(NSwag、Swagger Codegen等)自动生成消费者各种编程语言的源代码。
  • 测试工具用于执行 API 请求并动态验证响应。
  • 模拟服务器工具提供模拟服务器以返回静态或动态生成的示例响应。

因此,通过在 Web API 项目中使用 OpenAPI,我们可以通过维护基于实际数据传输类的数据注释、XML 注释和示例,直接从源代码或源代码自动生成文档。.NET 的两个主要 OpenAPI 实现是Swashbuckle和NSwag。在以下部分的示例中,我们将使用这些Swashbuckle工具。

在启用 OpenAPI 的 .NET 6.0 中创建新的 Web API

从 ASP.NET Core 5.0 开始,Web API 模板默认启用 OpenAPI 支持。模板包含对Swashbuckle的 NuGet 依赖,注册服务,并添加必要的中间件以生成基本OpenAPI definition文件并在 Web UI 中提供它(通过 Swagger UI 工具)。在以下说明中,我们将看到如何创建一个启用 OpenAPI 支持的新 Web API 项目。

打开 Visual Studio 2022(您可以从这里 下载)并选择“创建新项目”。

搜索并选择“ ASP.NET Core Web API ”模板,然后单击“下一步”。 

为新项目命名(例如“ TutorialWebApiDocumentation ”),选择保存位置,然后单击“下一步”。 

在“附加信息”对话框中,确认.NET 6.0选择了框架,并勾选了“启用 OpenAPI 支持”。然后点击“创建”。 

支持 OpenAPI 的 Web API 项目已准备就绪 🎉!在 .NET 6.0 中,没有Startup.cs文件(Roth D.,2021 年)。因此,服务注册和 HTTP 请求管道配置在文件中执行Program.cs。 

launchSettings.json文件默认配置为在项目启动时启动 Swagger 的 UI URL。 

点击开始调试按钮(或“调试”菜单 > “开始调试”),我们的应用将在浏览器中显示 Swagger UI。在 UI 中,我们可以看到默认的 GET/WeatherForecast端点及其相关信息(HTTP 响应代码、生成的示例等)。 

这是一个很好的开始!只需单击几下,我们的新 API 项目即可支持 OpenAPI。但是,我们可以配置和改进一些东西,以便为我们的 API 消费者提供更多信息。例如,我们可以执行下图和列表中所示的操作。但是,我们将在以下部分中看到更多丰富 API 文档的方法。

  • 设置适当的响应媒体类型(例如,application/json)。
  • 提供具有真实数据的示例(而不是使用虚拟数据自动生成的)。
  • 包含其他 HTTP 状态代码。例如,告知可能的错误 HTTP 状态代码(4xx 和 5xx)。

图 1.- 可能采取的措施来改进默认的 OpenAPI 文档。

在现有项目中提供 OpenAPI 文档

假设我们当前的项目提供多个版本的 API,并且我们希望为所有版本提供 OpenAPI 文档。为此,我们将使用在 .NET Nakama ( 2021 年 12 月) 中创建的项目。

为了提供 OpenAPI 文档,我们首先要安装Swashbuckle.AspNetCore NuGet 包。为了支持多个版本的 API 文档,我们需要安装Microsoft.AspNetCore.Mvc.Versioning.ApiExplorer NuGet 包。

图 2.- 安装 Microsoft.AspNetCore.Mvc.Versioning.ApiExplorer NuGet 包。

我们的下一步是注册一些服务并添加一些中间件。我创建了一些扩展方法,将所有必要的操作分组以实现此目的。您可以在此处找到扩展和示例的源代码。

Program.cs因此,我们可以在我们的(或以前的 .NET 版本中)下载、修改和使用以下扩展System.cs。此外,我们可以在此处源代码压缩包内Program.cs查看该文件的示例。

AddApiVersioningConfigured扩展(可以在 ConfigureApiVersioning.cs 中找到)已更新(与文章 .NET Nakama(2021 年 12 月)中提供的扩展相比),以支持我们文档的版本控制。

// Configure the API versioning properties of the project.
builder.Services.AddApiVersioningConfigured();

然后,我们应该使用文件AddSwaggerSwashbuckleConfigured中的扩展(位于 ConfigureSwaggerSwashbuckle.cs 文件中)Program.cs根据我们的需求配置 Swagger 生成器。在以下部分中,我们将详细介绍几种丰富场景。 

// Add a Swagger generator and Automatic Request and Response annotations:
builder.Services.AddSwaggerSwashbuckleConfigured();

在该ConfigureSwaggerSwashbuckleOptions.cs文件中,我们可以配置有关我们的 API 的基本信息(例如标题、描述、许可证等)(见下面图3)。

var info = new OpenApiInfo()
{Title = "Web API Documentation Tutorial",Version = description.ApiVersion.ToString(),Description = "A tutorial project to provide documentation for our existing APIs.",Contact = new OpenApiContact() { Name = "Ioannis Kyriakidis", Email = "info@dotnetnakama.com" },License = new OpenApiLicense() { Name = "MIT License", Url = new Uri("https://opensource.org/licenses/MIT") }
};

UseSwagger()在我们的文件中添加中间件Program.cs,以将生成的 OpenAPI 定义作为 JSON 文件提供,并将中间件UseSwaggerUI()用于为所有发现的 API 版本提供 Swagger-UI。在下面的示例中,我们仅在开发环境中提供 API 文档。但是,我们可以根据 API 受众决定在哪些环境中提供文档。请记住,我们只能在单独的项目中生成 JSON 文件并提供它们(例如,使用 Swagger UI)。

if (app.Environment.IsDevelopment())
{// Enable middleware to serve the generated OpenAPI definition as JSON files.app.UseSwagger();// Enable middleware to serve Swagger-UI (HTML, JS, CSS, etc.) by specifying the Swagger JSON endpoint(s).var descriptionProvider = app.Services.GetRequiredService<IApiVersionDescriptionProvider>();app.UseSwaggerUI(options =>{// Build a swagger endpoint for each discovered API versionforeach (var description in descriptionProvider.ApiVersionDescriptions){options.SwaggerEndpoint($"{description.GroupName}/swagger.json", description.GroupName.ToUpperInvariant());}});
}

最后,如果我们想在开始调试时看到 SwaggerUI,我们必须"launchUrl": "swagger"launchSettings.json文件中进行设置。

"TutorialWebApiDocumentation": {"commandName": "Project","dotnetRunMessages": true,"launchBrowser": true,"launchUrl": "swagger","applicationUrl": "https://localhost:44351;http://localhost:34885","environmentVariables": {"ASPNETCORE_ENVIRONMENT": "Development"}
},

下图展示了具有两个版本且包含基本信息的 API 的 Swagger UI 示例。

图 3.- 包含基本信息的 Swagger UI 示例。 

通过 XML 注释和属性丰富文档

在 C# 中,使用 XML 文档注释定义提取的 XML 文档的结构。文档注释支持多个 XML 标记,例如摘要、返回描述、异常、信息列表等。在本文中,我们将使用其中一些标记。有关 C# 推荐的 XML 标记的更多信息,请阅读 Wagner B. 等人 ( 2021 ) 的文章。

生成并阅读文档注释 (XML)

为了启用文档文件生成,我们应该将GenerateDocumentationFile选项设置为 True。然后,编译器将在我们的源代码中找到所有带有 XML 标签的注释字段并创建一个 XML 文档。

但是,当启用此选项时,编译器将为我们项目中没有 XML 文档注释的任何公共成员生成CS1591NoWarn警告。我们可以通过在选项中包含这些警告来排除这些警告。

因此,要启用该GenerateDocumentationFile选项并停止CS1591警告,我们应该:

  • 右键单击项目Solution Explorer并选择Edit Project File
  • 添加以下 PropertyGroup 部分(或在现有 PropertyGroup 中包含选项)。
<PropertyGroup><GenerateDocumentationFile>True</GenerateDocumentationFile><NoWarn>$(NoWarn);1591</NoWarn>
</PropertyGroup>

接下来,我们需要在 OpenAPI 定义文件中包含 XML 文档注释。为此,我们应该使用文件IncludeXmlComments中的方法ConfigureSwaggerSwashbuckle.cs,如下面的代码所示。

// Set the comments path for the XmlComments file.
string xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
string xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
options.IncludeXmlComments(xmlPath);

最后,我们应该使用三斜杠将 XML 注释包含在控制器操作中。例如,我们可以添加一个summary部分来描述执行的操作。下面图4中显示了 Swagger UI 的一部分,其中显示了 API 端点摘要。

/// <summary>
/// Get a list with all "<see cref="SampleResponse"/>" items.
/// </summary>
[HttpGet]
public IEnumerable<SampleResponse> Get()
{// …action code
}

图 4.- 带有 XML 注释(摘要标签)的 Swagger UI 示例。

API 响应(HTTP 代码和类型)

任何消费者都需要有用的信息,例如可能的 HTTP 状态代码及其响应主体。在下面图5中,我们可以看到一个示例,其中 API 端点可以返回其五个可能的 HTTP 状态代码(200、400、409、500 和 503)。为了丰富给定操作方法的响应元数据,我们应该:

  • 安装Swashbuckle.AspNetCore.Annotations NuGet 包。
  • 更新控制器操作以使用response标签和SwaggerResponse属性指定可能的响应代码及其响应类型(如果有)。

在下面的代码示例中,我们在response标签中设置了成功 HTTP 状态代码的响应描述。此外,我们还IEnumerable<SampleResponse>为成功响应设置了所有可能的 HTTP 状态代码和响应类型(例如)。

/// <summary>
/// Get a list with all "<see cref="SampleResponse"/>" items.
/// </summary>
/// <response code="200">Returns a list with the available sample responses.</response>
[HttpGet]
[SwaggerResponse(StatusCodes.Status200OK, Type = typeof(IEnumerable<SampleResponse>))]
[SwaggerResponse(StatusCodes.Status400BadRequest)]
[SwaggerResponse(StatusCodes.Status409Conflict)]
[SwaggerResponse(StatusCodes.Status500InternalServerError)]
[SwaggerResponse(StatusCodes.Status503ServiceUnavailable)]
public IEnumerable<SampleResponse> Get()
{// ...
}

图 5.- 具有多个响应 HTTP 状态代码的 Swagger UI 示例。

定义媒体类型(消费媒体和生产媒体)

为了定义适当的消费和生产媒体类型,我们可以使用[Consumes][Produces]属性来装饰我们的控制器。例如,如果我们使用application/json,我们可以使用上述属性来装饰我们的控制器,如下面的代码示例所示。在下面图6[Produces]显示了Swagger UI 中属性的效果。

[ApiController]
// ...other attributes
[Consumes("application/json")]
[Produces("application/json")]
public class HelloWorldController : ControllerBase
{// …controller's code
}

图 6.- 在 Swagger UI 中使用 [Produces] 属性的效果。

通过过滤器丰富文档

NuGet包Swashbuckle.AspNetCore.Filters提供了多种功能,可显著改善我们的 API 文档。例如,我们可以创建具有有效数据的有价值的请求和响应示例,包括安全要求、自定义请求和响应标头等。此外,我们可以使用这些功能手动测试我们的 API,只需使用 Swagger UI 即可,而无需修改自动生成的请求。

API 示例(请求和响应)

为了向请求和响应示例提供有价值且有效的数据,我们应该:

  • 安装Swashbuckle.AspNetCore.Filters NuGet 包。
  • 启用文件中的[SwaggerRequestExample]和的自动注释。为此,我们应该: [SwaggerResponseExample]ConfigureSwaggerSwashbuckle.cs
    • options.ExampleFilters();在 中使用AddSwaggerGen(options)
    • 通过注册来读取当前程序集的示例AddSwaggerExamplesFromAssemblies
services.AddSwaggerGen(options => {options.ExampleFilters();// ... other stuff
});
services.AddSwaggerExamplesFromAssemblies(Assembly.GetEntryAssembly());

然后,我们可以为我们的数据传输类(请求和响应)实现IExamplesProvider接口。在下面的源代码示例中,我们返回该类的一个示例,如下面图7SampleRequest所示。

using Swashbuckle.AspNetCore.Filters;
using TutorialWebApiDocumentation.V1.DTOs;namespace TutorialWebApiDocumentation.V1.Examples
{public class SampleRequestExample : IExamplesProvider<SampleRequest>{public SampleRequest GetExamples(){return new SampleRequest(){Id = 2,Name = "Hello DotNetNakama",};}}
}

图 7.- 请求 DTO 的 Swagger UI 示例。 

图 8.- 响应 DTO 的 Swagger UI 示例。

API 文档中的输入验证(数据注释和 Fluent)

如果我们使用属性来验证 DTO,那么验证会被识别并自动包含在 API 文档中。但是,如果我们对 DTO使用FluentValidationSystem.ComponentModel.DataAnnotations,则应执行以下步骤。

  • 安装MicroElements.Swashbuckle.FluentValidation NuGet 包。
  • 在中注册以下服务,ConfigureSwaggerSwashbuckle.cs以将流畅的验证规则添加到Swagger生成器中。
services.AddFluentValidationRulesToSwagger();

图 9.- 使用 DataAnnotations VS FluentValidation 时的 Swagger UI 示例。 

安全信息计划

为了提供有关我们正在使用的授权方案(例如 JWT Bearer)的安全信息,我们可以在ConfigureSwaggerSwashbuckle.cs文件中使用以下源代码来定义它。这样,Authorize按钮就会显示出来(下面图10),我们可以使用它来指定适当的值(例如下面图11中的 bearer token )。

options.OperationFilter<SecurityRequirementsOperationFilter>(true, "Bearer");
options.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
{ Description = "Standard Authorization header using the Bearer scheme (JWT). Example: \"bearer {token}\"",Name = "Authorization",In = ParameterLocation.Header,Type = SecuritySchemeType.ApiKey,Scheme = "Bearer"
});

图 10.- 带有授权按钮的 Swagger UI 示例。

图 11.- Swagger UI 示例用于设置 JWT 承载令牌。

标记需要授权的端点

我们的 API 端点可能需要授权(使用[Authorize]属性)或允许匿名请求。正如我们所理解的,在我们的 Swagger UI 中区分这些情况会很有帮助。为此,我们可以(Auth)在端点摘要旁边显示文本,以快速查看哪些端点需要授权(下面图12OperationFilter )。我们可以通过在文件中使用以下内容来执行此操作ConfigureSwaggerSwashbuckle.cs,如下所示:

options.OperationFilter<AppendAuthorizeToSummaryOperationFilter>();

图 12.- 带有授权指示器的 Swagger UI 示例。

概括

提供Web API documentation必要的信息(例如端点、数据契约等)来向我们的消费者描述我们的 Web API。但是,保持最新的 Web API 文档具有挑战性,需要时间和精力。因此,尽可能简单且自动化的流程将大有帮助。

提供OpenAPI Specification了一种描述 Web API 的标准化方法,使人类和计算机都可以生成、发现和理解 API 功能。在 ASP .NET Core 项目中,我们使用特定的属性和 XML 注释将所有需要的信息(例如 HTTP 响应代码、信息消息等)直接定义到我们的源代码中。因此,我们可以轻松地提供最新的文档,同时保持代码的更新。

我们需要的基本 OpenAPI 工具包括 a) 生成 OpenAPI 定义的工具和 b) 生成 API 文档(网页、PDF 等)的工具。本文介绍了如何使用 Swashbuckle 工具在 ASP.NET Core 项目(新建或现有)中创建包含丰富信息的 API 文档。

创建 Web API 文档时,我们的目标应该是提供消费者与我们的 Web API 通信所需的所有信息(无需访问我们的代码)。这样,我们可以缩短第一次 hello world (TTFHW) 调用的时间(即与我们的 Web API 集成的时间)。因此,让我们考虑一下我们的消费者,为他们创建漂亮而有价值的 Web API 文档。

参考

  • .NET Nakama (2021 年 12 月 4 日)。有关 ASP.NET Core 中的 Web API 版本控制的所有信息。https ://www.dotnetnakama.com/blog/all-about-web-api-versioning-in-asp-dotnet-core/
  • Roth D.(2021 年 8 月 10 日)。.NET 6 Preview 7 中的 ASP.NET Core 更新。https ://devblogs.microsoft.com/dotnet/asp-net-core-updates-in-net-6-preview-7/#minimal-host-and-template-improvements
  • Wagner B. 和 Warren G. (2021 年 11 月 29 日)。XML 文档注释。https: //docs.microsoft.com/en-us/dotnet/csharp/language-reference/xmldoc/
  • Wagner B. 等人(2021 年 11 月 30 日)。C# 文档注释的推荐 XML 标签。https: //docs.microsoft.com/en-us/dotnet/csharp/language-reference/xmldoc/recommended-tags

如果您喜欢这篇文章(或不喜欢),请随时为文章点赞、收藏,或在下面留下评论、建议,或只是打个招呼。你好,陌生人😉!

别忘了关注我,祝您有美好的一天😁。


http://www.ppmy.cn/news/1546675.html

相关文章

Python练习18

Python日常练习 题目&#xff1a; 请编fun函数&#xff0c;求44整型数组的主对角线元素的和。 说明&#xff1a; 如下图所示为一个44整型数组 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 测试用例&#xff1a; 1 2 3 4 5 6 7 8…

vue-h5:在h5中实现相机拍照加上身份证人相框和国徽框

1.基础功能 参考&#xff1a; https://blog.csdn.net/weixin_45148022/article/details/135696629 https://juejin.cn/post/7327353533618978842?searchId20241101133433B2BB37A081FD6A02DA60 https://www.freesion.com/article/67641324321/ https://github.com/AlexKrat…

Jmeter的安装和使用

使用场景&#xff1a; 我们需要对某个接口进行压力测试&#xff0c;在多线程环境下&#xff0c;服务的抗压能力&#xff1b;还有就是关于分布式开发需要测试多线程环境下数据的唯一性。 解决方案: jmeter官网连接&#xff1a;Apache JMeter - Apache JMeter™ 下载安装包 配…

2024年11月13日历史上的今天大事件早读

1125年11月13日 南宋著名诗人陆游出生 1587年11月13日 明代政治家海瑞逝世 1760年11月13日 清朝嘉庆帝颙琰出生 1907年11月13日 世界上第一架直升飞机在法国飞起 1909年11月13日 南社成立 1918年11月13日 北京将克林德碑改名“公理战胜” 1927年11月13日 黄麻起义 1945年…

sql注入之二次注入(sqlilabs-less24)

二阶注入&#xff08;Second-Order Injection&#xff09;是一种特殊的 SQL 注入攻击&#xff0c;通常发生在用户输入的数据首先被存储在数据库中&#xff0c;然后在后续的操作中被使用时&#xff0c;触发了注入漏洞。与传统的 SQL 注入&#xff08;直接注入&#xff09;不同&a…

C++的序列式容器(二)list

std::list 是 C 标准库中的双向链表容器&#xff0c;提供了快速的插入和删除操作。与 vector 不同&#xff0c;list 是链式存储结构&#xff0c;因此它不支持随机访问。 1. 概述 std::list 是一个双向链表容器&#xff0c;位于 <list> 头文件中。链表是一种线性表数据结…

Oracle RAC的thread

参考文档&#xff1a; Real Application Clusters Administration and Deployment Guide 3 Administering Database Instances and Cluster Databases Initialization Parameter Use in Oracle RAC Table 3-3 Initialization Parameters Specific to Oracle RAC THREAD Sp…

dapp获取钱包地址,及签名

npm install ethersimport {ethers} from ethers const accounts await ethereum.request({method: eth_requestAccounts}); // 获取钱包地址 this.form.address accounts[0] console.log("accounts:" this.address)const provider new ethers.BrowserProvider(…