Philip EliassonWriting about Episerver, .Net and web development
  • Start page
  • About me

Swagger documentation of your apis in your solution

2019-10-15 0 comments Article Uncategorized

When moving more and more towards JavaScript driven applications there is also a higher need for api´s. These api´s needs to be documented so that everyone in the team is able to consume them. A very good way to document api´s is to use Swagger which is an free available nuget package.

The only thing that could hold this back is that swagger by default is open for everyone but can off course be locked down in different ways. It could also be a case that you want to set roles on which api´s users can see documentation for.

To solve this I have created a custom attribute where you can set which role that is required to reach the documentation for each api.

To use this custom attribute, add following classes your project:

[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class)]
public class ShowInSwaggerRoleAttribute : Attribute
{
  private string role;

  public ShowInSwaggerRoleAttribute(string role = null)
  {
    this.role = role;
  }

  public virtual string Role
  {
    get { return role; }
  }
}
public class ShowInSwaggerFilter : IDocumentFilter
{
  public void Apply(SwaggerDocument swaggerDoc, SchemaRegistry schemaRegistry, IApiExplorer apiExplorer)
  {
    var filteredApisWithRole = apiExplorer.ApiDescriptions.Where(a => a.GetControllerAndActionAttributes<ShowInSwaggerRoleAttribute>().Any());
    var paths = new Dictionary<string, PathItem>(swaggerDoc.paths);

    swaggerDoc.paths.Clear();

    foreach (var apiDescription in filteredApisWithRole)
    {
      var swaggerRole = apiDescription.GetControllerAndActionAttributes<ShowInSwaggerRoleAttribute>().FirstOrDefault();
      if (swaggerRole != null)
      {
        if (swaggerRole.Role == null || HttpContext.Current.User.IsInRole(swaggerRole.Role))
        {
          var route = "/" + apiDescription.RelativePathSansQueryString();
          if (paths.Any(p => p.Key == route))
          {
            var path = paths.FirstOrDefault(p => p.Key == route);
            if (!swaggerDoc.paths.Contains(path) && !path.Key.ToLower().StartsWith("/episerver/"))
            {
              swaggerDoc.paths.Add(path);
            }
          }
        }
      }
    }
  }
}

 

To install swagger to your application:

  1. Install the nuget package Swashbuckle to your project
  2. Enable creation of XML documentation file in project settings:
  3. Edit SwaggerConfig.cs in the App_Start folder to:
    public class SwaggerConfig
    {
      public static void Register()
      {
        var thisAssembly = typeof(SwaggerConfig).Assembly;
    
        GlobalConfiguration.Configuration
          .EnableSwagger(c =>
            {
              c.DocumentFilter<ShowInSwaggerFilter>();
              c.ResolveConflictingActions(apiDescriptions => apiDescriptions.First());
              c.UseFullTypeNameInSchemaIds();
              c.SingleApiVersion("v1", "ExampleProject");
    
            })
          .EnableSwaggerUi(c =>
            {
              
            });
      }
    }

     

Now you just need to add the custom attribute to your controllers and decorate them with all descriptions that swagger needs, for example:

/// <summary>
/// Test Api
/// </summary>
[ShowInSwaggerRole("Administrators")]
public class TestController : ApiController
{
  /// <summary>
  /// Test
  /// </summary>
  /// <group>Test Api</group>
  /// <verb>GET</verb>
  /// <url>http://localhost:60808/api/testapi/test</url>
  /// <response code="200"><see cref="string"/> object retrieved</response>
  /// <returns></returns>
  [HttpGet]
  [Route("Api/Test/Test")]
  public string Test()
  {
    return "test";
  }
}

 

To use Episerver internal login just create a folder in your project on root level named “swagger” and add a web.config into it with following content:

<configuration>
  <system.web>
    <authorization>
      <deny users="?" />
    </authorization>
  </system.web>
  <system.webServer>
    <modules runAllManagedModulesForAllRequests="true" />
  </system.webServer>
</configuration>

 

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

Recent Posts

  • Swagger documentation of your apis in your solution
  • Automatic way to handle SVG icons with Episerver
  • Removing CreatedBy and UpdatedBy from Episerver Find index

Recent Comments

    Archives

    • October 2019
    • November 2017
    • July 2017

    Categories

    • Episerver CMS
    • Episerver Find
    • Uncategorized

    Copyright philipe.se 2017