Hidden swagger part web API interface

Time:2021-9-19

background

Swagger is the most popular document generation tool for rest APIs, and it is also an online testing tool for APIs. Powerful, who knows who uses it. I don’t have to promote it here. The problem to be solved today is: if some specific API interfaces are not displayed in swagger, that is, filter out some interfaces that do not want to be displayed from swagger? Generally, we use swagger to generate APIs by specifying packages to be scanned or scanning controllers with certain annotations. What if we want to filter out some specific APIs?

Implementation method

1. Add a feature and hide the swagger interface feature ID

/// 
        ///
        /// 
        /// 
        /// 
        public void Apply(SwaggerDocument swaggerDoc, DocumentFilterContext context)
        {
            foreach (ApiDescription apiDescription in context.ApiDescriptions)
            {
                if (apiDescription.TryGetMethodInfo(out MethodInfo method))
                {
                    if (method.ReflectedType.CustomAttributes.Any(t => t.AttributeType == typeof(HiddenApiAttribute))
                            || method.CustomAttributes.Any(t => t.AttributeType == typeof(HiddenApiAttribute)))
                    {
                        string key = "/" + apiDescription.RelativePath;
                        if (key.Contains("?"))
                        {
                            int idx = key.IndexOf("?", System.StringComparison.Ordinal);
                            key = key.Substring(0, idx);
                        }
                        swaggerDoc.Paths.Remove(key);
                    }
                }
            }
        }
    }

2. Add filters, customize swagger hide filters

/// 
    ///Hide swagger interface attribute ID
    /// 
    [AttributeUsage(AttributeTargets.Method | AttributeTargets.Class)]
    public class HiddenApiAttribute : System.Attribute
    {
    }

3. Modify swaggerconfig and inject filter

#region Swagger

            services.AddSwaggerGen(c =>
          {
              c.SwaggerDoc("v1", new Info
              {
                  Version = "v1",
                  Title = "interface document",
                  Description = "interface document - Basic",
                  TermsOfService = "https://example.com/terms",
                  Contact = new Contact
                  {
                      Name = "XXX1111",
                      Email = "[email protected]",
                      Url = "https://example.com/terms"
                  }
                  ,
                  License = new License
                  {
                      Name = "Use under LICX",
                      Url = "https://example.com/license",
                  }
              });

              c.SwaggerDoc("v2", new Info
              {
                  Version = "v2",
                  Title = "interface document",
                  Description = "interface document - Basic",
                  TermsOfService = "https://example.com/terms",
                  Contact = new Contact
                  {
                      Name = "XXX2222",
                      Email = "[email protected]",
                      Url = "https://example.com/terms"
                  }
                   ,
                  License = new License
                  {
                      Name = "Use under LICX",
                      Url = "https://example.com/license",
                  }
              });
              c.OperationFilter();
              c.DocumentFilter();
              var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
              var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
              c.IncludeXmlComments(xmlPath);
              c.IncludeXmlComments(Path.Combine(AppContext.BaseDirectory, $"CompanyName.ProjectName.ICommonServer.xml"));
          });

            #endregion Swagger

test

/////// 
        ///////Check whether the account number exists
        /////// 
        ///////(required) the account or mobile phone number data = true already exists, data = false does not exist
        ///////Testing
        ////[HttpGet, Route("existAccount")]
        ////[ApiExplorerSettings(GroupName = "v2")]
        //////[HiddenApi]
        ////public R ExistAccount([FromQuery] string account)
        ////{
        ////    return R.Suc(true);
        ////}

Open source address

https://github.com/conanl5566/Sampleproject/tree/master/src/03%20Host/CompanyName.ProjectName.HttpApi.Host