Pradeep Kumar
Pradeep Kumar

Reputation: 6979

Customize version number in Swagger

I'm using the default swagger implementation with my dotnet core webapi. I would like the actual version number to appear instead of the template whenever version number is changing from the "select a definition" dropdown on top right corner.

So, for example when v2 is selected from the dropdown, it should appear like this

enter image description here

instead of this,

enter image description here

Any clues how this can be done?

Upvotes: 3

Views: 2622

Answers (1)

bugrakosen
bugrakosen

Reputation: 603

You can use Microsoft.AspNetCore.Mvc.Versioning and custom swagger filter.

Create custom document filter;

public class ReplaceVersionWithExactValueInPathFilter : IDocumentFilter
{
    public void Apply(OpenApiDocument swaggerDoc, DocumentFilterContext context)
    {
        var paths = swaggerDoc.Paths;

        swaggerDoc.Paths = new OpenApiPaths();

        foreach (var path in paths)
        {
            var key = path.Key.Replace("v{version}", swaggerDoc.Info.Version);

            var value = path.Value;

            swaggerDoc.Paths.Add(key, value);
        }
    }
}

Add versioning and swagger services to your service collection;

services.AddApiVersioning(config =>
{
    // Specify the default API Version
    config.DefaultApiVersion = new ApiVersion(1, 0);

    // If the client hasn't specified the API version in the request, use the default API version number 
    config.AssumeDefaultVersionWhenUnspecified = true;

    // Advertise the API versions supported for the particular endpoint
    config.ReportApiVersions = true;
});

//Adding swagger services
services.AddSwaggerGen(options =>
{
    //other configurations 

    options.SwaggerDoc("v1.0", new OpenApiInfo
    {
        Version = "v1.0",
        Title = "Your Api Title",
        Description = "Your Api Description",
        TermsOfService = new Uri("https://yourcompany.com"),
        Contact = new OpenApiContact { Name = "Your Company", Email = "[email protected]", Url = new Uri("https://yourcompany.com") },
        License = new OpenApiLicense { Name = "MIT", Url = new Uri("https://opensource.org/licenses/MIT") }
    });

    options.SwaggerDoc("v2.0", new OpenApiInfo
    {
        Version = "v2.0",
        Title = "Your Api Title",
        Description = "Your Api Description",
        TermsOfService = new Uri("https://yourcompany.com"),
        Contact = new OpenApiContact { Name = "Your Company", Email = "[email protected]", Url = new Uri("https://yourcompany.com") },
        License = new OpenApiLicense { Name = "MIT", Url = new Uri("https://opensource.org/licenses/MIT") }
    });
        
    options.DocumentFilter<ReplaceVersionWithExactValueInPathFilter>();

    //other configurations 
});

Register Swagger and SwaggerUI middleware;

app.UseSwagger(c =>
{
    c.SerializeAsV2 = true;
    c.RouteTemplate = "api/docs/{documentName}/docs.json";
}).UseSwaggerUI(c =>
{
    c.SwaggerEndpoint($"/api/docs/v1.0/docs.json", "v1.0");
    c.SwaggerEndpoint($"/api/docs/v2.0/docs.json", "v2.0");
});

Then configure your controller;

[Route("api/v{version:apiVersion}/[controller]")]
[ApiController]
public class TestsController : ControllerBase
{

    [HttpPost("Test")]
    [ApiVersion("1.0")]
    [ApiExplorerSettings(GroupName = "v1.0")]
    public IActionResult TestV1()
    {
        return Ok();
    }
    
    [HttpPost("Test")]
    [ApiVersion("2.0")]
    [ApiExplorerSettings(GroupName = "v2.0")]
    public IActionResult TestV2()
    {
        return Ok();
    }

}

If you want to remove version header from your document you should use this;

public class VersionHeaderFilter : IOperationFilter
{
    public void Apply(OpenApiOperation operation, OperationFilterContext context)
    {
         if (operation.Parameters != null)
         {
             var versionParameter = operation.Parameters.SingleOrDefault(p => p.Name == "version");

             if (versionParameter != null) 
                 operation.Parameters.Remove(versionParameter);
         }
    }
}

services.AddSwaggerGen(options =>
{
     //other configurations 

     options.OperationFilter<VersionHeaderFilter>();

     //other configurations 
});

This should work.

Upvotes: 7

Related Questions