Ultimate ASP.NET CORE 6.0 Web API --- 读书笔记(30)
30 Documenting API With Swagger
本文内容来自书籍: Marinko Spasojevic - Ultimate ASP.NET Core Web API - From Zero To Six-Figure Backend Developer (2nd edition)
需要本书和源码的小伙伴可以留下邮箱,有空看到会发送的
API文档是指示如何有效使用和集成API的过程
因此,它可以被看作是一个简明的参考手册,包含了使用 API 所需的所有信息,包含了函数、类、返回类型、参数等的详细信息,并得到了教程和示例的支持
30.1 About Swagger
Swagger是一种语言无关的REST APIs的描述规范,也被称作OpenAPI,它允许我们在不知道实际实现的前提下,了解服务的功能。Swagger最大限度地减少了集成 API 所需的工作量。类似地,它还可以帮助 API 开发人员快速、准确地记录他们的 API。
默认情况下,一个名为 Swagger.json 的文档是由基于我们的 API 的 Swagger 工具生成的。它描述了我们的 API 的功能以及如何通过 HTTP 访问它。
30.2 Swagger Integration Into Our Project
我们可以使用包Swashbuckle很方便地集成到我们的项目中
有三个主要的组件:
- Swashbuckle.AspNetCore.Swagger:包含了Swagger对象模型和输出Swagger.json文档的中间件
- Swashbuckle.AspNetCore.SwaggerGen:根据我们的
routes、controller、models来构建Swagger文档的生成器 - Swashbuckle.AspNetCore.SwaggerUI:一个内嵌的Swagger UI,它将
Swagger JSON翻译成一个丰富的,可定制的,用于描述API功能的页面
接下来就看看Swagger如何集成,首先需要安装包到主项目中Swashbuckle.AspNetCore,然后配置
public static void ConfigureSwagger(this IServiceCollection services)
{
services.AddSwaggerGen(s =>
{
s.SwaggerDoc("v1", new OpenApiInfo
{
Title = "Code Maze API", Version = "v1"
});
s.SwaggerDoc("v2", new OpenApiInfo
{
Title = "Code Maze API", Version = "v2"
});
});
}
builder.Services.ConfigureSwagger();
app.UseSwagger();
app.UseSwaggerUI(s =>
{
s.SwaggerEndpoint("/swagger/v1/swagger.json", "Code Maze API v1");
s.SwaggerEndpoint("/swagger/v2/swagger.json", "Code Maze API v2");
});
最后,在控制器上标记,不同版本的接口,对于没有标记的那些控制器,会在两个组内都拥有
[Route("api/companies")]
[ApiController]
[ApiExplorerSettings(GroupName = "v1")]
public class CompaniesController : ControllerBase
[Route("api/companies")]
[ApiController]
[ApiExplorerSettings(GroupName = "v2")]
public class CompaniesV2Controller : ControllerBase
在项目启动之后,可以输入URI/swagger/v1/swagger.json,就可以看到文档了
30.3 Adding Authorization Support
然而我们的项目的资源都是受保护的,所以在使用Swagger测试接口的时候,发送是不成功的,所以我们需要配置Swagger
public static void ConfigureSwagger(this IServiceCollection services)
{
services.AddSwaggerGen(s =>
{
s.SwaggerDoc("v1", new OpenApiInfo
{
Title = "Code Maze API", Version = "v1"
});
s.SwaggerDoc("v2", new OpenApiInfo
{
Title = "Code Maze API", Version = "v2"
});
s.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
{
In = ParameterLocation.Header,
Description = "Place to add JWT with Bearer",
Name = "Authorization",
Type = SecuritySchemeType.ApiKey,
Scheme = "Bearer"
});
s.AddSecurityRequirement(new OpenApiSecurityRequirement()
{
{
new OpenApiSecurityScheme
{
Reference = new OpenApiReference
{
Type = ReferenceType.SecurityScheme,
Id = "Bearer"
},
Name = "Bearer",
},
new List<string>()
}
});
});
}
重新启动项目之后,可以发现,所有的接口都带锁了,我们需要按照之前认证流程,登陆,获取token,请求头中带有token,需要注意的是,在Swagger中填写token的时候,需要加上前缀Bearer
30.4 Extending Swagger Configuration
Swagger提供了一些选项,让我们能够自定义扩展文档和UI
首先,我们可以编写API的信息和描述,比如Contact、License、Description
s.SwaggerDoc("v1", new OpenApiInfo
{
Title = "Code Maze API",
Version = "v1",
Description = "CompanyEmployees API by CodeMaze",
TermsOfService = new Uri("https://example.com/terms"),
Contact = new OpenApiContact
{
Name = "John Doe",
Email = "John.Doe@gmail.com",
Url = new Uri("https://twitter.com/johndoe"),
},
License = new OpenApiLicense
{
Name = "CompanyEmployees API LICX",
Url = new Uri("https://example.com/license"),
}
});
然后,我们希望描述一下接口,还有出入参数的含义,可以通过原生的文档注释,生成文档XML,然后再将其配置到Swagger,就可以了
如果需要开启XML文档,需要suppress warning 1591,因为开启XML文档之后,我们并不是所有的类或者方法都会编写文档注释,我们只会在Presentation编写,所以,我们需要在Presentation项目的配置文件中配置
<!-- xxx.csproj -->
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<DocumentationFile>CompanyEmployees.Presentation.xml</DocumentationFile>
<OutputPath></OutputPath>
<NoWarn>1701;1702;1591</NoWarn>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
<NoWarn>1701;1702;1591</NoWarn>
</PropertyGroup>
var xmlFile =
$"{typeof(Presentation.AssemblyReference).Assembly.GetName().Name}.xml";
var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
s.IncludeXmlComments(xmlPath);
最后,只需要在控制器上添加文档注释就可以了
如果需要关注接口的返回值和响应码,可以使用文档注释和注解一起
/// <summary>
/// Creates a newly created company
/// </summary>
/// <param name="company"></param>
/// <returns>A newly created company</returns>
/// <response code="201">Returns the newly created item</response>
/// <response code="400">If the item is null</response>
/// <response code="422">If the model is invalid</response>
[HttpPost(Name = "CreateCompany")]
[ProducesResponseType(201)]
[ProducesResponseType(400)]
[ProducesResponseType(422)]

浙公网安备 33010602011771号