Show only selected controllers in swagger-swashbuckle UI

岁酱吖の 提交于 2020-07-18 08:51:12

问题


I am currently using swagger in my project and i have more than 100 controllers there. I guess due to the large number of controller, swagger UI documentation page takes more than 5 min to load its controller. Is it possible to select specific controllers at the UI page and load options for them only? Or else there are other methods to load UI page faster? Help me!


回答1:


you can use ApiExplorerSettings on either controller to ignore a controller completely or on a method.

[ApiExplorerSettings(IgnoreApi = true)]
public class MyController
{
    [ApiExplorerSettings(IgnoreApi = true)]
    public string MyMethod
    {
      ...
    }
}



回答2:


Using swashbuckle's document filter you can remove some elements of the generated specification after the fact, and they would then not be included on the integrated swagger-ui. Create a class such as the below:

using System;
using System.Web.Http.Description;
using Swashbuckle.Swagger;

internal class SwaggerFilterOutControllers : IDocumentFilter
{
    void IDocumentFilter.Apply(SwaggerDocument swaggerDoc, SchemaRegistry schemaRegistry, IApiExplorer apiExplorer)
    {
        foreach (ApiDescription apiDescription in apiExplorer.ApiDescriptions)
        {
            Console.WriteLine(apiDescription.Route.RouteTemplate);

            if ((apiDescription.RelativePathSansQueryString().StartsWith("api/System/"))
                || (apiDescription.RelativePath.StartsWith("api/Internal/"))
                || (apiDescription.Route.RouteTemplate.StartsWith("api/OtherStuff/"))
                )
            {
                swaggerDoc.paths.Remove("/" + apiDescription.Route.RouteTemplate.TrimEnd('/'));
            }
        }
    }
}

and then edit your SwaggerConfig.cs file to include the filter:

        GlobalConfiguration.Configuration
            .EnableSwagger(c =>
                    c.DocumentFilter<SwaggerFilterOutControllers>();

Note that while the controllers have been removed from the specification, other items such as the result models will still be included in the specification and might still be slowing down the page load.

It could also be slow simply due to enumerating all of the controllers/models etc in the first place, in which case this might not help.

Edit: I noticed it would regenerate the whole definition every time the UI page was viewed (which could be crippling in your scenario). Fortunately it's super easy to cache this (which should be fine as it shouldn't change at runtime for the majority of people).

Add this to your config:

c.CustomProvider((defaultProvider) => new CachingSwaggerProvider(defaultProvider));

and use this class shamelessly copied from https://github.com/domaindrivendev/Swashbuckle/blob/master/Swashbuckle.Dummy.Core/App_Start/CachingSwaggerProvider.cs

using Swashbuckle.Swagger;
using System.Collections.Concurrent;

namespace <your namespace>
{
    public class CachingSwaggerProvider : ISwaggerProvider
    {
        private static ConcurrentDictionary<string, SwaggerDocument> _cache =
            new ConcurrentDictionary<string, SwaggerDocument>();

        private readonly ISwaggerProvider _swaggerProvider;

        public CachingSwaggerProvider(ISwaggerProvider swaggerProvider)
        {
            _swaggerProvider = swaggerProvider;
        }

        public SwaggerDocument GetSwagger(string rootUrl, string apiVersion)
        {
            string cacheKey = string.Format("{0}_{1}", rootUrl, apiVersion);
            return _cache.GetOrAdd(cacheKey, (key) => _swaggerProvider.GetSwagger(rootUrl, apiVersion));
        }
    }
}



回答3:


swaggerDoc.paths.Remove("/" + apiDescription.Route.RouteTemplate.TrimEnd('/'));did not remove anything for me. So,

internal class SwaggerFilterOutControllers : IDocumentFilter
{
    void IDocumentFilter.Apply(SwaggerDocument swaggerDoc, SchemaRegistry schemaRegistry, IApiExplorer apiExplorer)
    {
        foreach (var item in swaggerDoc.Paths.ToList())
        {
            if (!(item.Key.ToLower().Contains("/api/v1/xxxx") ||
                  item.Key.ToLower().Contains("/api/v1/yyyy")))
            {
                swaggerDoc.Paths.Remove(item.Key);
            }
        }
    }
}



回答4:


In response to the previous answer, this is the updated code for ASP.NET Core. I also added the feature to remove models.

using System;
using System.Linq;
using System.Web.Http;
using Swashbuckle.AspNetCore.SwaggerGen;
using Swashbuckle.AspNetCore.Swagger;

using Microsoft.AspNetCore.Mvc.ApiExplorer;

internal class SwaggerFilterOutControllers : IDocumentFilter
{

    void IDocumentFilter.Apply(SwaggerDocument swaggerDoc, DocumentFilterContext context)
    {
        foreach (var item in swaggerDoc.Paths.ToList())
        {
            if (!(item.Key.ToLower().Contains("/api/endpoint1") ||
                  item.Key.ToLower().Contains("/api/endpoint2")))
            {
                swaggerDoc.Paths.Remove(item.Key);
            }
        }

        swaggerDoc.Definitions.Remove("Model1");
        swaggerDoc.Definitions.Remove("Model2");
    }
}


来源:https://stackoverflow.com/questions/41757920/show-only-selected-controllers-in-swagger-swashbuckle-ui

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!