Swagger-接口分组篇

发布时间 2023-06-01 14:18:07作者: 相遇就是有缘

分组需求

开发中使用Swagger进行Api接口测试时常常会遇到以下情况:1.Controller中的Action、Model、DTO过多导致单页面加载时页面响应速度太慢  2.接口太多,如果用一个页面展示查找某个接口会很麻烦。虽然可以采用搜索方式解决此问题,但不推荐。

分组功能实现

1. 新建目录ApiGroup,并在该目录下创建三个文件

ApiGroupAttribute.cs(控制器特性)

ApiGroupNames.cs(系统分组枚举)

GroupInfoAttribute.cs(给系统分组枚举值增加相关信息的特性,这个主要是用于在Swagger分组时可关联Title,Version,Description值)

 1 using Microsoft.AspNetCore.Mvc.ApiExplorer;
 2 using System;
 3 using System.Collections.Generic;
 4 using System.Linq;
 5 using System.Threading.Tasks;
 6 
 7 namespace Ming.ApiGroup
 8 {
 9     /// <summary>
10     /// 系统分组特性
11     /// </summary>
12     public class ApiGroupAttribute : Attribute, IApiDescriptionGroupNameProvider
13     {
14         public ApiGroupAttribute(ApiGroupNames name)
15         {
16             GroupName = name.ToString();
17         }
18 public string GroupName { get; set; } 19 } 20 }
 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Threading.Tasks;
 5 
 6 namespace Ming.ApiGroup
 7 {
 8     /// <summary>
 9     /// 系统分组枚举值
10     /// </summary>
11     public enum ApiGroupNames
12     {
13         [GroupInfo(Title ="登录认证模块",Description ="登录认证相关模块")]
14         Auth,
15         [GroupInfo(Title = "权限模块", Description = "权限功能相关模块,如用户管理、角色管理、菜单管理、部门管理等待")]
16         PerMission,
17         [GroupInfo(Title = "单据模块", Description = "单据模块相关接口,如申购单、采购订单")]
18         BillCode
20 } 21 }
 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Threading.Tasks;
 5 
 6 namespace Ming.ApiGroup
 7 {
 8     /// <summary>
 9     /// 系统模块枚举注释
10     /// </summary>
11     public class GroupInfoAttribute : Attribute
12     {
13         public string Title { get; set; }
14         public string Version { get; set; }
15         public string Description { get; set; }
16     }
17 }

 

2.修改AddSwaggerGen方法

 1 public void ConfigureServices(IServiceCollection services)
 2 {
 3     
 4     #region Swagger
 5     services.AddSwaggerGen(options =>
 6     {
 7         //遍历ApiGroupNames所有枚举值生成接口文档,Skip(1)是因为Enum第一个FieldInfo是内置的一个Int值
 8         typeof(ApiGroupNames).GetFields().Skip(1).ToList().ForEach(f =>
 9         {
10             //获取枚举值上的特性
11             var info = f.GetCustomAttributes(typeof(GroupInfoAttribute), false).OfType<GroupInfoAttribute>().FirstOrDefault();
12             options.SwaggerDoc(f.Name, new Swashbuckle.AspNetCore.Swagger.Info
13             {
14                 Title = info?.Title,
15                 Version = info?.Version,
16                 Description = info?.Description
17             });
18         });
19         //没有加特性的分到这个NoGroup上
20         options.SwaggerDoc("NoGroup", new Swashbuckle.AspNetCore.Swagger.Info
21         {
22             Title = "无分组"
23         });
24         //判断接口归于哪个分组
25         options.DocInclusionPredicate((docName, apiDescription) =>
26         {
27             if (docName == "NoGroup")
28             {
29                 //当分组为NoGroup时,只要没加特性的都属于这个组
30                 return string.IsNullOrEmpty(apiDescription.GroupName);
31             }
32             else
33             {
34                 return apiDescription.GroupName == docName;
35             }
36         });
37 }

 

3.修改UseSwaggerUI方法

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{

    #region Swagger
    app.UseSwagger();
    app.UseSwaggerUI(options =>
    {
        //遍历ApiGroupNames所有枚举值生成接口文档,Skip(1)是因为Enum第一个FieldInfo是内置的一个Int值
        typeof(ApiGroupNames).GetFields().Skip(1).ToList().ForEach(f =>
        {
            //获取枚举值上的特性
            var info = f.GetCustomAttributes(typeof(GroupInfoAttribute), false).OfType<GroupInfoAttribute>().FirstOrDefault();
            options.SwaggerEndpoint($"/swagger/{f.Name}/swagger.json", info != null ? info.Title : f.Name);

        });
        options.SwaggerEndpoint("/swagger/NoGroup/swagger.json", "无分组");
    });
    #endregion
}

 

4.控制器分组

[ApiGroup](ApiGroupNames.Auth)
public class HomeController:ControllerBase{
}

备注:未加特性标注的控制器则默认划分 “无分组”模块中。