C. Molendijk
C. Molendijk

Reputation: 2834

C# .net core swagger trying to use Multiple API Versions, but all end-points are in all documents

We are trying to separate our API versions into different Swagger documents. We have configured everything as described in https://github.com/domaindrivendev/Swashbuckle.AspNetCore#generate-multiple-swagger-documents.

So we have configured two versions like this:

services.AddSwaggerGen(c =>
{
    c.SwaggerDoc("v1", new OpenApiInfo { Title = "My API - V1", Version = "v1" });
    c.SwaggerDoc("v2", new OpenApiInfo { Title = "My API - V2", Version = "v2" });
})

Also we have configured to see them in swagger ui. like this:

app.UseSwagger();
app.UseSwaggerUI(c =>
{
    c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API - V1");
    c.SwaggerEndpoint("/swagger/v2/swagger.json", "My API - V2");
});

To set the end-points in the right version we use the following convention:

public class ApiExplorerGroupPerVersionConvention : IControllerModelConvention
{
    public void Apply(ControllerModel controller)
    {
        // e.g. "Controllers.V1":
        var controllerNamespace = controller.ControllerType.Namespace; 
        var apiVersion = controllerNamespace.Split('.').Last().ToLower();

        controller.ApiExplorer.GroupName = apiVersion;
    }
}

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc(c =>
        c.Conventions.Add(new ApiExplorerGroupPerVersionConvention())
    );
}

Now we see the two documents in the UI and we can go to the json files. So that works. But the all the end-points are in both the documents. We expected that we see the v1 end-points in v1 and the v2 end-points in v2. But that is not the case. If we debug the convention then we see that it set the groupname correctly. If we don't set the group name we don't see the end-points at all.

So it all seems to work, except that it is not separated. Did we miss something?

Upvotes: 31

Views: 26209

Answers (2)

C. Molendijk
C. Molendijk

Reputation: 2834

The problem was that I had the following line in my swagger config:

services.AddSwaggerGen(c =>
{
...
c.DocInclusionPredicate((_, api) => !string.IsNullOrWhiteSpace(api.GroupName));
...
});

The doc inclusion prediction was always giving back true. That why it added all the end-points to all the docs. We don't need the doc inclusion prediction as we already add the and-points to to correct group by the ApiExplorerGroupPerVersionConvention

Upvotes: 12

Tony
Tony

Reputation: 20132

This is how I config swagger with multi version

services.AddSwaggerGen(c =>
{
    c.SwaggerDoc("v1", new Info
    {
        Version = "v1",
        Title = "Awesome CMS Core API V1",
        Contact = new Contact { Name = "Tony Hudson", Email = "", Url = "https://github.com/ngohungphuc" }
    });

    c.SwaggerDoc("v2", new Info
    {
        Version = "v2",
        Title = "Awesome CMS Core API V2",
        Contact = new Contact { Name = "Tony Hudson", Email = "", Url = "https://github.com/ngohungphuc" }
    });

    c.ResolveConflictingActions(apiDescriptions => apiDescriptions.First());
});


app.UseSwagger();
app.UseSwaggerUI(c =>
{
    c.SwaggerEndpoint($"/swagger/v1/swagger.json", "Awesome CMS Core API V1");
    c.SwaggerEndpoint($"/swagger/v2/swagger.json", "Awesome CMS Core API V2");
});

And in my controller I need to config like this

[ApiVersion("1.0")]
[ApiExplorerSettings(GroupName = "v1")]
[Route("api/v{version:apiVersion}/Account/")]

Upvotes: 40

Related Questions