Swagger/OpenAPI 的 API 文档

OpenAPI规范是描述API功能的文档,该文档的的信息基于控制器和模型中的XML属性注释。它也是OpenAPI流的核心部分,用于驱动SwaggerUI之类的工具。一般命名为openapi.json

下面是为简洁起见而缩减的 OpenAPI 规范的示例:

{
  "openapi": "3.0.1",
  "info": {
    "title": "API V1",
    "version": "v1"
  },
  "paths": {
    "/api/Todo": {
      "get": {
        "tags": [
          "Todo"
        ],
        "operationId": "ApiTodoGet",
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/ToDoItem"
                  }
                }
              },
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/ToDoItem"
                  }
                }
              },
              "text/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/ToDoItem"
                  }
                }
              }
            }
          }
        }
      },
      "post": {
        …
      }
    },
    "/api/Todo/{id}": {
      "get": {
        …
      },
      "put": {
        …
      },
      "delete": {
        …
      }
    }
  },
  "components": {
    "schemas": {
      "ToDoItem": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "format": "int32"
          },
          "name": {
            "type": "string",
            "nullable": true
          },
          "isCompleted": {
            "type": "boolean"
          }
        },
        "additionalProperties": false
      }
    }
  }
}

 

SwaggerUI 提供了基于 Web 的 UI,它使用生成的 OpenAPI 规范提供有关服务的信息。

Swashbuckle 有三个主要组成部分:

  1. Swagger: 将 SwaggerDocument 对象公开为 Json 终结点的Swagger对象模型和中间件。以便于我们对文档内容的设置,和中间件的调用。
  2. SwaggerGen:从路由、控制器和模型直接生成 SwaggerDocument 对象的 Swagger 生成器。 它通常与 Swagger 终结点中间件结合,以自动公开 Swagger JSON。 这样我们在编写API时,Swagger便会自动识别我们的API并加入SwaggerDocument。公开到UI。
  3. SwaggerUI:Swagger UI 工具的嵌入式版本。它解释了Swagger Json文档来生成具有我们描述性的Web API,还具有对公共方法的内置测试工具

我们引入NuGet工具包时,选择最新的“Swashbuckle.AspNetCore”包。然后配置Swagger中间件和服务:

 

中间件:

我们需要添加Swagger中间件将SwaggerDocument文档暴露出,然后使用SwaggerUI中间件解释 SwaggerDocument 来生成具有描述性的Web API,并指定我们要暴露的 Swagger Json endpoint。

注意UseSwaggerUI方法调用启用了UseStaticFile中间件。在一些 UseStaticFile 会影响的中间件出现时,需要考虑中间件的引用顺序。

所以大概是这个样子:

app.UseSwagger();
app.UseStatciFile(); //useSwaggerUI自动引入 app.UseSwaggerUI(options
=> { //暴露Json文档终结点 options.SwaggerEndpoint("/swagger/v1/swagger.json", "Api V1");
   }); app.UseRouting(); app.UseAuthorization(); app.UseEndpoints(endpoints
=> { endpoints.MapControllers(); });

可在 http://localhost:<port>/swagger 找到 Swagger UI。 通过 Swagger UI 浏览 API。要在应用的根 (http://localhost:<port>/) 处提供 Swagger UI,请将 RoutePrefix 属性设置为空字符串:

app.UseSwaggerUI(c =>
{
    c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1");
    c.RoutePrefix = string.Empty;
});

 

服务:

将SwaggerGen注册在服务中,便可以将控制器的公共方法和模型的信息生成到SwaggerDocument中以便于暴露至Web UI,另外我们可以额外的指定信息:

传递给 AddSwaggerGen 方法的配置操作会添加诸如作者、许可证和说明的信息:使用 OpenApiInfo 类修改 UI 中显示的信息:

services.AddSwaggerGen(c =>
{
    c.SwaggerDoc("v1", new OpenApiInfo()
    {
        Version = "v1",
        Title = "Xieyi API",
        Description = "xieyi's simple example ASP.NET Core Web API",
        TermsOfService = new Uri("https://www.baidu.com"),
        Contact = new OpenApiContact
        {
            Name = "Zhou Xieyi",
            Email = "zhouxieyi@qq.com",
            Url = new Uri("https://www.sina.com.cn")
        },
        License = new OpenApiLicense
        {
            Name = "Go to Learn Swashbuckle",
            Url = new Uri("https://docs.microsoft.com/zh-cn/aspnet/core/tutorials/getting-started-with-swashbuckle?view=aspnetcore-5.0&tabs=visual-studio")
        }
    });

});

效果展示:

启用XML注释,反射用于生成与 Web API 项目相匹配的 XML 文件名。 AppContext.BaseDirectory属性用于构造 XML 文件的路径。 一些 Swagger 功能(例如,输入参数的架构,或各自属性中的 HTTP 方法和响应代码)无需使用 XML 文档文件即可起作用。

var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
c.IncludeXmlComments(xmlPath);

Tips:若启动时,出现不能发现XML文档,则是没有生成,检查此处。项目属性中。

对于大多数功能(即方法摘要以及参数说明和响应代码说明),必须使用 XML 文件。

 <remarks> 元素可提供我们自定义的指定信息,提供更加可靠的Swagger UI,比如我们认为POST方法中ExameValue不够具体,我们可以自定义我们的备注提供给SwaggerUI:

/// <summary>
/// Creates a TodoItem.
/// </summary>
/// <remarks>
/// Sample request:
///
///     POST /Todo
///     {
///        "id": 1,
///        "name": "Item1",
///        "isCompleted": true
///     }
/// </remarks>
/// <param name="item">model to add</param>
/// <returns></returns>

效果图:

 我们可以对模型进行必填特性来改变Json中的架构,并可以自定义规定响应内容类型:

[Produces("application/json")]
[Route("api/[controller]")]
[ApiController]
public class TodoController : ControllerBase
{
    private readonly TodoContext _context;

描述响应类型:

在我们进行POST操作时,通常会判断模型是否为null,若为null则返回400,但文档描述中可能只有我们返回的200状态码,那么就会使使用者对我们的API描述不够全面。我们可以自己规定响应类型和错误代码。

/// <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);
}

Swagger UI 现在清楚地记录预期的 HTTP 响应代码:

posted @ 2021-05-24 22:56  zhouslthere  阅读(1299)  评论(0编辑  收藏  举报