ASP.NET Core使用Swagger实现接口文档并分组

  每一个程序员都有重构他人代码的冲动,但是,每一个程序员都不会有写接口文档的冲动。

  据我所知,在.net项目中,很多同行的中小型项目接口文档都使用Swagger,最近几个朋友一起讨论,有没有比较好用的类似Swagger接口文档开源项目,其中有朋友反馈说api太多的情况下,使用Swagger文档就是一个灾难,因为接口太多,前端开发人员很难找到自己想要的接口,因为所有的接口和接口实体类都展示在一个页面上。

  说实话,我以前还真没有关注过这个问题,这两天我有个项目,接口也比较多,自己在测试接口的时候才发现确实存在这种情况。由于公司内部还有一套自己的接口文档框架,使用体验相对于Swagger更优,所以我就想Swagger怎么就不能像我们自己的框架那样,将webapi分组呢。后来查了些资料,Swagger团队早就为我想到了,结论就是Swagger也支持接口分组。

  一般我们分组都是按照控制器来分组,一个webapi控制器也就是要给小的模块,具体实现我们往下看:

接入Swagger

1.在NuGet包管理器中安装Swashbuckle.AspNetCore

2.添加配置文件:swaggergroupconfigs.json,文件内容如下:

{
  "swaggergroupconfigs": [
    {
      "GroupName": "Web",
      "Title": "Web模块",
      "Version": "V1.0"
    },
    {
      "GroupName": "Order",
      "Title": "订单模块",
      "Version": "V1.0"
    },
    {
      "GroupName": "System",
      "Title": "系统模块",
      "Version": "V1.0"
    }
  ]
}

3.加载分组配置文件:

        public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureAppConfiguration((hostBuilderContext, configurationBuilder) =>
                {
                    var env = hostBuilderContext.HostingEnvironment;
                    //optional:如果是必要的配置文件,可选就要设定为false,当文件不存在就会引发FileNotFoundException。
                    //reloadOnChange :如果文件被更新,是否更新IConfiguration实例的值。
                    configurationBuilder.AddJsonFile($"appsettings.json", optional: true, reloadOnChange: true);
                    configurationBuilder.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true);

                    configurationBuilder.AddJsonFile($"hosting.json", optional: true, reloadOnChange: true);
                    configurationBuilder.AddJsonFile($"hosting.{env.EnvironmentName}.json", optional: false, reloadOnChange: true).Build();

                    configurationBuilder.AddJsonFile($"swaggergroupconfigs.json", optional: true, reloadOnChange: true);
                    configurationBuilder.AddJsonFile($"swaggergroupconfigs.{env.EnvironmentName}.json", optional: false, reloadOnChange: true).Build();
                })
                .ConfigureWebHostDefaults(webBuilder =>
                {
                    webBuilder.UseStartup<Startup>();
                }).UseSerilog(dispose: true);
      }

4.注入Swagger服务

     public void ConfigureServices(IServiceCollection services)
        {
            services.AddControllers();//Swagger接口模块分组配置
            var swaggergroupconfigs = Configuration.GetSection("swaggergroupconfigs").Get<List<SwaggerGroupConfig>>();
            services.AddSwaggerGen(swoption =>
            {
                swoption.SwaggerDoc("v1", new Microsoft.OpenApi.Models.OpenApiInfo()
                {
                    Version = "1.2.10",
                    Title = "Api Document",
                    Description = "Api Document"
                });
                #region Swagger接口模块分组配置
                swaggergroupconfigs.ForEach(group =>
                {
                    swoption.SwaggerDoc(group.GroupName, new OpenApiInfo { Title = group.Title, Version = group.Version });   //分组显示
                });
                #endregion
                var basePath = Path.GetDirectoryName(typeof(Program).Assembly.Location);//获取应用程序所在目录(绝对,不受工作目录影响,建议采用此方法获取路径)
                var xmlPath = Path.Combine(basePath, "Research.Web.xml");
                swoption.IncludeXmlComments(xmlPath, true);
            });
        }

5.启用SwaggerUi中间件服务

  public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
  {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            app.UseRouting();

            app.UseAuthorization();

            //自定义中间件
            app.UseRequestMiddlewares();

            //启用中间件服务生成Swagger作为JSON终结点
            app.UseSwagger();
            //启用中间件服务对swagger-ui,指定Swagger JSON终结点
            var swaggerGroupCofigs = Configuration.GetSection("swaggergroupconfigs").Get<List<SwaggerGroupConfig>>();
            app.UseSwaggerUI(suoption =>
            {
                suoption.SwaggerEndpoint("/swagger/v1/swagger.json", "Api Document");
                suoption.RoutePrefix = string.Empty;
                swaggerGroupCofigs.ForEach(group =>
                {
                    suoption.SwaggerEndpoint($"/swagger/{group.GroupName}/swagger.json", group.Title);  //分组显示
                });
            });

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
            });
        }
    }
    public class SwaggerGroupConfig
    {
        public string GroupName { get; set; }
        public string Title { get; set; }
        public string Version { get; set; }
    }

6.在控制器类上添加分组特性(注意:GroupName值等于分组配置文件中对应的字段值)

using System.Collections.Generic;
using System.Linq;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Research.Web.Common;

namespace Research.Web.Controllers
{
    [ApiExplorerSettings(GroupName = "Order")]
    [ApiController]
    [Route("Order")]
    public class OrderController : ControllerBase
    {
        [HttpGet("Details")]
        public JsonResult Details(int id)
        {
            var claims = HttpContext.User.Claims.ToList();
            var list = new List<object>();
            claims.ForEach(claim =>
            {
                list.Add(new
                {
                    key = claim.Type,
                    value = (claim.Type.Equals("nbf") || claim.Type.Equals("exp")) ? claim.Value.UnixTimeToDateTime() : claim.Value
                });
            });
            return new JsonResult(list);
        }
    }
}

6.运行,查看效果如下:

 

原文地址:https://www.cnblogs.com/pudefu/p/14143390.html