web-dev-qa-db-ja.com

選択したコントローラーのみをswagger-swashbuckle UIに表示する

現在プロジェクトでSwaggerを使用していますが、100以上のコントローラーがあります。コントローラーの数が多いため、Swagger UIのドキュメントページでコントローラーを読み込むのに5分以上かかると思います。 UIページで特定のコントローラーを選択して、それらのオプションのみをロードすることは可能ですか?それともUIページをより速くロードする他の方法がありますか?助けて!

13
Subash Kharel

スワッシュバックルのドキュメントフィルターを使用すると、生成された仕様の一部の要素を事後に削除でき、統合されたswagger-uiに含まれなくなります。以下のようなクラスを作成します。

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

次に、SwaggerConfig.csファイルを編集してフィルターを含めます。

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

コントローラーは仕様から削除されていますが、結果モデルなどの他のアイテムは仕様に含まれているため、ページの読み込みが遅くなる可能性があることに注意してください。

また、最初にすべてのコントローラー/モデルなどを列挙するだけで遅くなる場合もあります。その場合、これは役に立たない可能性があります。

編集:UIページが表示されるたびに定義全体が再生成されることに気づきました(シナリオで問題になる可能性があります)。幸いなことに、これをキャッシュするのは非常に簡単です(実行時に大多数の人が変更してはいけないので問題ありません)。

これを設定に追加してください:

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

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));
        }
    }
}
9
Rory

いずれかのコントローラーでApiExplorerSettingsを使用して、コントローラーを完全に無視するか、メソッドで無視できます。

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

前の回答に応じて、これはASP.NET Coreの更新されたコードです。モデルを削除する機能も追加しました。

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");
    }
}
2
Andrew Samole

swaggerDoc.paths.Remove("/" + apiDescription.Route.RouteTemplate.TrimEnd('/')); dは何も削除しませんでした。そう、

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);
            }
        }
    }
}
2
madufit1