Skip to Content
author.name

5 minutes read


Swagger is removed starting from .NET 9


You've probably seen or heard on the internet that Swagger was deprecated with .NET 9 that was released on the 12th November of this year. Let's discover the details and learn about the options available for developers using .NET ecosystem that will allow providing OpenAPI support for ASP.NET Core Web APIs starting from .NET 9.

The context of this decision

This decision was an official announcement made by the ASP.NET Core team through a Github issue, which spread some concern amongst the .NET community.

The inclusion of the Swachbuckle.AspNetCore package as a dependency dates back to .NET 5, which provided built-in support for OpenAPI along with the Swagger web-based UI to test and interact with an API.

As described by the author of the announcement, the shipping of the Swachbuckle.AspNetCore package as a dependency of ASP.NET Core web API templates will be suspended beginning with .NET 9.

Why ?

The reason why Microsoft decided to ditch the package is the lack of interactivity from the maintainer, although the package repo showed some activity recently, but there are still numerous issues that need to be addressed and resolved, besides there was no official release for .NET 8.

The ASP.NET Core team's plan is to get rid of the dependency on Swachbuckle.AspNetCore from the web API templates and extend the in-house library Microsoft.AspNetCore.OpenApi to provide OpenAPI support.

That does not mean the Swachbuckle packages are going anywhere, they can still be used like any other packages such as NSwag which allows —in addition to OpenAPI support— client and server generation from an OpenAPI document.

Goodbye Swagger UI

The fact that OpenAPI support becomes a first-class citizen in ASP.NET Core, doesn't mean we'll be having all the Swagger tools that were provided by 3rd party libraries and allowed interacting with Open API documents, like the Swagger UI, client and server generation tools, etc...

Unfortunately the Swagger aspect is being removed with the release of .NET 9, and developers will have to rely on other libraries or custom development to bring back a UI to test and interact with an ASP.NET Core web API.

Current state-of-the-art

When you generate a new project using the ASP.NET Core minimal web API template as an option, your Program.cs file will look like this :

Program.cs
var builder = WebApplication.CreateBuilder(args);

builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

var app = builder.Build();

if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}

app.UseHttpsRedirection();

var summaries = new[]
{
    "Freezing",
    "Bracing",
    "Chilly",
    "Cool",
    "Mild",
    "Warm",
    "Balmy",
    "Hot",
    "Sweltering",
    "Scorching"
};

app.MapGet("/weatherforecast", () =>
{
    var forecast =  Enumerable.Range(1, 5).Select(index =>
        new WeatherForecast
        (
            DateOnly.FromDateTime(DateTime.Now.AddDays(index)),
            Random.Shared.Next(-20, 55),
            summaries[Random.Shared.Next(summaries.Length)]
        ))
        .ToArray();
    return forecast;
})
.WithName("GetWeatherForecast")
.WithOpenApi();

app.Run();

record WeatherForecast(DateOnly Date, int TemperatureC, string? Summary)
{
    public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
}

In the preceding code :

  • builder.Services.AddSwaggerGen(); adds OpenAPI/Swagger services to the DI container of ASP.NET Core.
  • app.UseSwagger(); configures the HTTP request pipeline to serve the OpenAPI document.
  • app.UseSwaggerUI(); configures the HTTP request pipeline to serve the Swagger UI endpoints.

The csproj file holds a reference to the Swachbuckle.AspNetCore NuGet package :

csproj
<Project Sdk="Microsoft.NET.Sdk.Web">

  <PropertyGroup>
    <TargetFramework>net8.0</TargetFramework>
    <Nullable>enable</Nullable>
    <ImplicitUsings>enable</ImplicitUsings>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="8.0.5" />
    <PackageReference Include="Swashbuckle.AspNetCore" Version="6.4.0" />
  </ItemGroup>

</Project>

What are the options with .NET 9 ?

As mentionned earlier, with the release of .NET 9 the Swachbuckle.AspNetCore package will be removed as a dependency from web API templates.

If you don't stick to LTS versions of .NET (which is something I discourage), there a few changes that needs to be made to switch to using the Microsoft's OpenAPI library.

First thing to do is to get rid of the Swachbuckle.AspNetCore package, and update the Microsoft.AspNetCore.OpenApi package to the latest version starting from 9.0 and including pre-release versions:

csproj
<Project Sdk="Microsoft.NET.Sdk.Web">

  <PropertyGroup>
    <TargetFramework>net9.0</TargetFramework>
    <Nullable>enable</Nullable>
    <ImplicitUsings>enable</ImplicitUsings>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="9.0.*-*" />
    <PackageReference Include="Swashbuckle.AspNetCore" Version="6.4.0" />
  </ItemGroup>

</Project>

The extension methods provided by Swachbuckle.AspNetCore should be replaced by the ones provided by the Microsoft.AspNetCore.OpenApi package :

  • builder.Services.AddOpenApi() registers OpenAPI/Swagger-related services.
  • app.MapOpenApi() enables the endpoint serving the generated OpenAPI document in JSON format.
Program.cs
var builder = WebApplication.CreateBuilder(args);

builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
builder.Services.AddOpenApi();

var app = builder.Build();

if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
    app.MapOpenApi();
}

app.UseHttpsRedirection();

// ...

app.Run();

With that the OpenAPI document is ready to be served at the /openapi/v1.json endpoint.

Options for OpenAPI document customization

Numerous options are provided for customizing the generated OpenAPI document :

  • The document can be customized by changing it's name, OpenAPI version, the route the OpenAPI document is served at.
  • Caching is an option to avoid document generation on each HTTP request.
  • The access to an OpenAPI endpoint can be limited to only authorized users.

Customizing with Transformers

The OpenAPI document can also be customized with transformers, which is useful for scenarios like adding top-level information to an OpenAPI document, adding parameters to all operations, modifying descriptions of parameters and so on.

This sample from Microsoft's documentation demonstrates the use of a transformer to add JWT bearer-related schemes to the OpenAPI document's top level :

Program.cs
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.OpenApi;
using Microsoft.Extensions.DependencyInjection;

var builder = WebApplication.CreateBuilder();

builder.Services.AddAuthentication().AddJwtBearer();

builder.Services.AddOpenApi(options =>
{
    options.UseTransformer<BearerSecuritySchemeTransformer>();
});

var app = builder.Build();

app.MapOpenApi();

app.MapGet("/", () => "Hello world!");

app.Run();

internal sealed class BearerSecuritySchemeTransformer(
  IAuthenticationSchemeProvider authenticationSchemeProvider) : IOpenApiDocumentTransformer
{
    public async Task TransformAsync(
      OpenApiDocument document,
      OpenApiDocumentTransformerContext context,
      CancellationToken cancellationToken)
    {
        var authenticationSchemes = await authenticationSchemeProvider.GetAllSchemesAsync();
        if (authenticationSchemes.Any(authScheme => authScheme.Name == "Bearer"))
        {
            var requirements = new Dictionary<string, OpenApiSecurityScheme>
            {
                ["Bearer"] = new OpenApiSecurityScheme
                {
                    Type = SecuritySchemeType.Http,
                    Scheme = "bearer", // "bearer" refers to the header name here
                    In = ParameterLocation.Header,
                    BearerFormat = "Json Web Token"
                }
            };
            document.Components ??= new OpenApiComponents();
            document.Components.SecuritySchemes = requirements;
        }
    }
}

And that's about it when it comes to what Microsoft will be providing with it's in-house OpenAPI support. No UI, no tools to generate client code, So what are the options if we want ad-hoc testing to be built into our APIs ?

OpenAPI tooling options

Keep using the Swagger UI

You can still use the Swagger UI package, which you'll have to install manually and configure to serve the Swagger UI endpoint :

Terminal
dotnet add package Swashbuckle.AspNetCore.SwaggerUI

Configure the Swagger UI middleware with the OpenAPI document route :

Program.cs
var builder = WebApplication.CreateBuilder(args);

builder.Services.AddOpenApi();

var app = builder.Build();

if (app.Environment.IsDevelopment())
{
    app.MapOpenApi();
    app.UseSwaggerUI(options =>
    {
        options.SwaggerEndpoint("/openapi/v1.json", "v1");
    });
}

app.UseHttpsRedirection();

// ...

app.Run();

Use Scalar interactive API documentation

Scalar is an open-source highly customizable platform that offers a set of tools for interacting with APIs, generating and customizing API references based on an OAS file.

Scalar can be integrated as a NuGet package into ASP.NET Core web APIs :

Terminal
dotnet add package Scalar.AspNetCore

To configure the middleware that will be serving the Scalar API reference UI, add the following lines to your Program.cs :

Program.cs
var builder = WebApplication.CreateBuilder(args);

builder.Services.AddOpenApi();

var app = builder.Build();

if (app.Environment.IsDevelopment())
{
    app.MapOpenApi();
    app.MapScalarApiReference();
}

app.UseHttpsRedirection();

// ...

app.Run();

By default Scalar uses the OpenAPI document route /openapi/v1.json which can be customized using the middleware options.

The Scalar API reference UI is served at /scalar/v1 by default which can also be customized.

Wrap Up

In conclusion, ASP.NET Core team's decision will provide a more streamlined and integrated approach for handling OpenAPI support within the ASP.NET Core ecosystem.

Developers can still leverage the Swagger UI package a.k.a Swachbuckle or switch to modern alternatives like the Scalar API documentation platform that offers a more robust and customizable solution for interacting with OpenAPI documents.

Exploring with new customization and tooling options will ensure that API documentation and testing remain efficient and effective, it will also help the community to continue building and maintaining high-quality web APIs in the evolving .NET landscape.