Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to filter out datatypes from Swagger schema?

I'm using Swasbuckle 5.6.

My controller has a method inherited from a third-party base that is being used company-wide.

    [ProducesResponseType(typeof(HealthCheckActionResult), (int)HttpStatusCode.OK)]
    public HealthCheckActionResult Get()
    {
        return new HealthCheckActionResult(healthCheckService, healthCheckOptions);
    }

As soon as I add that method to my controller, I see how Swagger UI bloats its schema definitions with lots of CLR internal types:

schema bloated

This huge schema causes UI to freeze often when using for quick API tests.

I tried the answer from https://stackoverflow.com/a/61313313/217823 but it did not work because SchemaRepository keys do not contain full namespace names of those unneeded datatypes.

Assuming I have no control over the HealthCheckActionResult class (it comes from the third-party library), what is a proper way to get rid of all the bloat it brings into the Swagger schema?

like image 870
JustAMartin Avatar asked Oct 18 '25 08:10

JustAMartin


1 Answers

I ended up with a solution that ignores all the System types, except ones that have conflicting names with my own types:

    // filter to stop the Swagger schema from bloating
    // because of API results that return complex CLR types
    internal class SwaggerExcludeClrTypesFilter : ISchemaFilter
    {
        private readonly string[] blacklist;
        // keep types that have matching System type names with our model
        private readonly string[] whitelist = new[] { "Currency" };

        public SwaggerExcludeClrTypesFilter()
        {
            var mscorlib = typeof(string).Assembly;
            var types = mscorlib.GetTypes()
                                .Where(t => t.Namespace?.Contains("System") == true);
            blacklist = types.Select(t => t.Name)
                .Where(t => !whitelist.Contains(t)).ToArray();
        }

        public void Apply(OpenApiSchema schema, SchemaFilterContext context)
        {
            if (schema.Properties != null)
            {
                foreach (var prop in schema.Properties)
                {
                    if (prop.Value.Reference != null
                        && blacklist.Contains(prop.Value.Reference.Id))
                    {
                        prop.Value.Reference = null;
                    }
                }
            }

            foreach (var key in blacklist)
            {
                context.SchemaRepository.Schemas.Remove(key);
            }
        }
    }

And then in ConfigureServices method in Startup class:

services.AddSwaggerGen(c =>
            {
                ...

                // remove some third-party types that slow Swagger UI down
                c.SchemaFilter<SwaggerExcludeClrTypesFilter>();
like image 146
JustAMartin Avatar answered Oct 21 '25 11:10

JustAMartin