swagger 是什么?
swagger 是一套框架,作用是自动化生成 .NET 的 Web API 项目的 API 文档。
ASP.NET Core 官方提供了简单的 Swagger 使用文档:ASP.NET Web API Help Pages using Swagger
Getting Started
首先我们要安装 Swashbuckle.AspNetCore 的 Nuget 包
1
Install-Package Swashbuckle.AspNetCore -Pre
然后我们可以在 Startup.cs 中的 ConfigureServices 方法中注册 Swagger 文档生成器,这里可以定义一个或多个需要生成的文档
1
2
3
4
5
6services.AddMvc();
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new Info { Title = "My API", Version = "v1" });
});我们需要确保所有的 API 方法和非路径的参数都有明确的 Http 和 From 绑定修饰符
1
2
3
4
5
6
7[ ]
public void Create([FromBody]Product product)
...
[HttpGet]
public IEnumerable<Product> Search([FromQuery]string keywords)
...注: 省略参数绑定修饰符则默认为请求 (query) 字段
在 Configure 方法中添加中间件来暴露 Swagger 生成的文档 JSON
1
app.UseSwagger();
此时你可以启动应用并在 “/swagger/v1/swagger.json.” 下看到 Swagger 生成的 JSON
(可选)如果你想得到交互式的文档,可以添加 swagger-ui 中间件。需要指定 Swagger JSON 源
1
2
3
4app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1");
});在 “/swagger” 下可以看到这个交互式的页面
Swashbuckle & ApiExplorer
Swashbuckle 十分依赖 ApiExplorer 。ApiExplorer 是一项位于 ASP.NET Core 之上的 Metadata 层的服务。如果服务集使用的是 AddMvc 方法引导 MVC 栈的话那么会自动注册 ApiExplorer_。然而如果是用 _AddMvcCore 来自行引导 MVC stack 的话你需要手动添加 Api Explorer 服务:
1 | services.AddMvcCore() |
组件
Swashbuckle 包含三个包:Swagger 生成器, 暴露 JSON 格式 Swagger 文档的中间件和使用这个 JSON 暴露 swagger-ui 的中间件。 你可以通过 “Swashbuckle.AspNetCore” 包一起下载这些包或根据自己的需要独立下载。详细说明如下表所示
Package | Description |
---|---|
Swashbuckle.AspNetCore.Swagger | 用一个 JSON API 暴露 SwaggerDocument 对象。在返回一个序列化的 JSON 之前,这个包需要注册一个 ISwaggerProvider 的实现用于生成 Swagger 文档 |
Swashbuckle.AspNetCore.SwaggerGen | 用于注入第一个组件需要的 ISwaggerProvider 的实现。这个特定的实现可以用你的路由(routes)、控制器(controllers)和模型(models)自动生成 Swagger 文档 |
Swashbuckle.AspNetCore.SwaggerUI | 暴露一个嵌入版本的 swagger-ui。你可以指定 ui 从哪个 API 获取Swagger JSON,然后 ui 会使用 JSON 生成交互式文档 |
配置 & 自定义
Swashbuckle.AspNetCore.Swagger
修改 Swagger JSON 路径
Swagger JSON 默认暴露在 /swagger/{documentName}/swagger.json
路径下。在启用中间件时我们可以自行修改这个路径。自定义的路径必须包含 {documentName}
字段。
1 | app.UseSwagger(c => |
NOTE: 如果同时也使用了 SwaggerUI 中间件,那么我们还需要更新 Swagger UI 的配置:
1 | app.UseSwaggerUI(c => |
使用 HTTP 请求信息修改 Swagger
如果我们想使用当前请求的某些信息设置 Swagger metadata,那么可以注册一个过滤器。
1 | app.UseSwagger(c => |
SwaggerDocument 和当前的 HttpRequest 都会被传递至过滤器。这个方法提供了很大的灵活性。例如你可以赋值给 host
属性(如上所示),你也可以检查 session 信息或者是 Authoriation header 来验证用户权限。
Swashbuckle.AspNetCore.SwaggerGen
列举 HTTP responses
Swashbuckle 默认会为所有方法生成 200
responses。如果这个方法返回一个 DTO,那么这个 DTO 将会被用来生成 HTTP responses body 的 schema,例如:
1 | [ ] |
Will produce the following response metadata:
1 | responses: { |
指定 HTTP responses
如果你想要指定一个状态码和/或其他 responses,或者需要返回的不是 DTO 而是 IActionResult_,你可以用 ASP.NET Core 中的 _ProducesResponseTypeAttribute 描述特定的 response,例如:
1 | [ ] |
这种写法会得到的 response metadata:
1 | responses: { |
使用 XML 注释生成描述
为了增强可读性,控制器和模型可以添加 XML 文档注释,并在注册 Swashbuckle 时将这些注释包含进 Swagger JSON:
打开项目的“属性”选项,选择“生成”标签页并勾上“ XML 文档文件”。然后当你生成项目时可以它会自动生成一个包含所有 XML 注释的文件。
此时如果某个类或方法没有使用 XML 注释,那么会产生一个生成警告。如果想要去掉这个警告,在此页的“禁止显示警告”选项中添加警告码“1591”即可。
在注册 Swashbuckle 时引用 XML 注释文件来生成 Swagger JSON:
1
2
3
4
5
6
7
8
9
10
11
12
13services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1",
new Info
{
Title = "My API - V1",
Version = "v1"
}
);
var filePath = Path.Combine(PlatformServices.Default.Application.ApplicationBasePath, "MyApi.xml");
c.IncludeXmlComments(filePath);
}方法注释应当有 summary、 remarks 和 response 标签。
1
2
3
4
5
6
7
8
9
10
11
12/// <summary>
/// Retrieves a specific product by unique id
/// </summary>
/// <remarks>Awesomeness!</remarks>
/// <response code="200">Product created</response>
/// <response code="400">Product has missing/invalid values</response>
/// <response code="500">Oops! Can't create your product right now</response>
[ ]
[ ]
[ ]
[ ]
public Product GetById(int id)重新生成项目,XML 注释文件会被更新。你可以打开 Swagger JSON 页面看看这些注释是怎么映射进对应的 Swagger 文档的。
注:你也可以通过给 model 以及它们的属性添加 summary 标签的方式生成 Swagger 文档。如果你有多个 XML 注释文件(例如控制器和 model 是独立的类库),你可以多次调用 IncludeXmlComments 方法,他们会被合并进输出的 Swagger JSON.
提供全局 API Metadata
除了 Paths_, _Operations 和 _Responses_,Swashbuckle 还提供了全局 metadata (详见 http://swagger.io/specification/#swaggerObject)。例如,你可以为你的 API、服务项、甚至是联系方式和证书信息提供一个完整的描述:
1 | c.SwaggerDoc("v1", |
使用 IntelliSense 可以看到哪些字段是可用的。
未完待更。