Supporting both Swagger v2 and OpenApi v3 in .NET 6

OpenApi is the proper standard to describe RESTful APIs. But there are many environments that still require good old Swagger. For me, it was in Azure, when specifying the API definition.

/supporting-both-swagger-and-open-api/azure-api-definition.png

.NET 6 allows you to easily create metadata, but it produces only OpenAPI v3. Changing it to Swagger v2 is quite easy though:

app.UseSwagger(options => options.SerializeAsV2 = true);

But I didn't want to sacrifice OpenAPI v3 because of it. This is the code that I eventually came up with:

builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen(options =>
{
  options.SwaggerDoc("myapi", new OpenApiInfo { Title = "My API", Version = "v1" });
  options.EnableAnnotations();
});

var app = builder.Build();

app.UseSwagger(options =>
{
  options.SerializeAsV2 = true;
  options.RouteTemplate = "swagger/{documentName}/swaggerV2.json";
});

app.UseSwagger(options =>
{
  options.SerializeAsV2 = false;
  options.RouteTemplate = "swagger/{documentName}/openapiV3.json";
});

app.UseSwaggerUI(options => {
  options.SwaggerEndpoint("/swagger/myapi/openapiV3.json", "OpenApi v3");
  options.SwaggerEndpoint("/swagger/myapi/swaggerV2.json", "Swagger v2");
});

The {documentName} refers to the name you specify in the AddSwaggerGen() method. The code above uses myapi as the name for the swagger document. In this case, I only have one swagger doc.

By specifying multiple endpoints, I can select which one I want in the swagger UI.

/supporting-both-swagger-and-open-api/swagger-ui.png

That's it. Enjoy!