使用.NET 6開發TodoList應用(27)——實現API的Swagger文檔化


系列導航及源代碼

需求

在日常開發中,我們需要給前端提供文檔化的API接口定義,甚至需要模擬架設一個fake服務用來調試接口字段。或者對於后端開發人員來說,我們可以通過導入這個接口定義文件到Postman或者其他API客戶端,省去我們手動錄入的麻煩。所以本文就實現如何使用Swagger來管理API接口文檔化。

但是在本文中,我們不涉及關於NSwag的相關內容,通過NSwag,我們甚至可以直接生成前端可以使用的接口定義。關於NSwag的使用方法,請參考:NSwag 和 ASP.NET Core 入門以及官方文檔RicoSuter/NSwag

目標

實現TodoList項目的接口文檔化。

原理與思路

在使用IDE或者cli生成新的Web API項目的時候,項目模版里已經自帶了Swashbuckle.AspNetCore包用來生成swagger文檔,我們需要使用這個包來實現相關功能。

實現

實現基礎的Swagger API文檔

Program中極有可能已經添加了SwaggerGen服務了,我們可以做一點小修改,因為之前我們寫過兩個版本的TodoItemController,希望將兩個版本也反映到swagger文檔中:

// 省略其他...
builder.Services.AddSwaggerGen(s =>
{
    s.SwaggerDoc("1.0", new OpenApiInfo { Title = "TodoList API", Version = "1.0"});
    s.SwaggerDoc("2.0", new OpenApiInfo { Title = "TodoList API", Version = "2.0"});
});

中間件的引入我們也可以修改一下:

if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI(s =>
    {
        s.SwaggerEndpoint("/swagger/1.0/swagger.json", "TodoList API v1.0");
        s.SwaggerEndpoint("/swagger/2.0/swagger.json", "TodoList API v2.0");
    });
}

如果在API接口版本控制的那一章我們不是使用的通過更改URL的方式實現的API多版本,那么現在只需要對應版本的Controller上添加:

  • TodoItemController.cs
[Route("/todo-item")]
[ApiExplorerSettings(GroupName = "1.0")]
[ApiController]
public class TodoItemController : ControllerBase
// 省略其他...

以及

  • TodoItemV2Controller.cs
[Route("/todo-item")]
[ApiExplorerSettings(GroupName = "2.0")]
[ApiController]
public class TodoItemV2Controller : ControllerBase
// 省略其他...

如果是使用URL路徑實現不同版本API的文檔,可以參考這篇文章的實現:ASP.NET Core 3.1 WebApi Swagger與API版本控制的美妙結合

為Swagger添加認證授權功能

為了添加授權支持,我們可以修改Swagger服務選項如下,增加授權配置:

  • Program.cs
// 省略其他
s.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
{
    In = ParameterLocation.Header,
    Description = "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>()
    }
});

此外因為我們需要驗證Issuer和Audience信息,所以需要在Token中攜帶這些信息,這樣Swagger才能授權成功,修改IdentityService發放Token中獲取Claims的邏輯:

  • IdentityService.cs
private async Task<List<Claim>> GetClaims()
{
    // 演示了返回用戶名和Role兩個claims
    var claims = new List<Claim>
    {
        new(ClaimTypes.Name, User!.UserName),
        // 使用fallback去填充這兩個字段,實際項目里可能不需要這樣做
        new(JwtRegisteredClaimNames.Iss, _jwtConfiguration.ValidIssuer ?? "TodoListApi"),
        new(JwtRegisteredClaimNames.Aud, _jwtConfiguration.ValidAudience ?? "https://localhost:5050")
    };

    var roles = await _userManager.GetRolesAsync(User);
    claims.AddRange(roles.Select(role => new Claim(ClaimTypes.Role, role)));

    return claims;
}

驗證

啟動Api項目,打開swagger地址,可以看到API版本選擇,以及授權控制都在界面上有所顯示。
image

具體的切換查看我就不貼截圖了,大家可以自己試一試。

一點擴展

導入API客戶端

右擊swagger界面上的json文件鏈接選擇另存為,再去對應的API客戶端導入json文件即可。
image

image

Postman在這方面做的比較好的是它能夠按照json文件內接口的結構關系生成對應的文件夾結構。

生成fake服務端

可以去這里:Swagger Editor,上傳swagger json文件,選擇生成服務端或者客戶端。
image

為swagger生成完整的數據定義及API注釋文檔

需要開啟XML注釋功能,為此我們同時需要禁止1591warning(為了避免對所有的方法、類、字段發出沒有xml注釋文檔的警告)。修改項目設置如下:

<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
  <DocumentationFile>TodoList.Api.xml</DocumentationFile>
  <OutputPath></OutputPath>
  <NoWarn>1701;1702;1591</NoWarn>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
  <NoWarn>1701;1702;1591</NoWarn>
</PropertyGroup>

修改SwaggerGen注入的配置:

  • TodoList.Api.csproj
var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
s.IncludeXmlComments(xmlPath);

我們以CreateTodoList接口為例去添加xml注釋,

  • TodoListController.cs
/// <summary>
/// 創建新的TodoList,只有Administrator角色的用戶有此權限
/// </summary>
/// <param name="command">創建TodoList命令</param>
/// <returns></returns>
[HttpPost]
[Authorize(Policy = "OnlyAdmin")]
[ServiceFilter(typeof(LogFilterAttribute))]
public async Task<ApiResponse<Domain.Entities.TodoList>> Create([FromBody] CreateTodoListCommand command)
{
    return ApiResponse<Domain.Entities.TodoList>.Success(await _mediator.Send(command));
}

再打開swagger文檔查看,可以看到swagger文檔現在已經有接口說明了:
image

總結

在本文中我們實現了swagger文檔的生成和一些配置選項的作用,如果需要用到更多OpenAPI相關的特性,推薦熟悉一下NSwag這個組件,它提供了更加強大的功能。

下一篇文章我們實現程序的健康檢查功能。

參考資料

  1. NSwag 和 ASP.NET Core 入門
  2. RicoSuter/NSwag
  3. ASP.NET Core 3.1 WebApi Swagger與API版本控制的美妙結合


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM