dotnet / dotnet/aspnetcore

Support Deprecation Metadata in the API Explorer

Open
#43,493 10 comments 4 reactions 0 assignees View on GitHub
api-suggestion area-minimal area-mvc
Dominant language
C#
Stars
38.4k
Forks
10.9k
Avg merge
2d 6h
Merged PRs (30d)
290

Description

## Background and Motivation

The API Explorer has been the pinnacle of sharing API metadata across different ASP.NET Core libraries. The concept of a _deprecated_ API exists in a number of different libraries such as ASP.NET API Versioning, Swashbuckle, NSwag, and OpenAPI .NET to name a few. Each library has its own method of describing a deprecated API, without any shared metadata, developers are required to create their own bridges to connect the two.

While not strictly required, it is reasonable to have the existing API Explorer metadata discovery indicate an API is deprecated when the `ObsoleteAttribute` is applied.

## Proposed API

```diff
namespace Microsoft.AspNetCore.Mvc.ApiExplorer;

public class ApiDescription
{
+ ///
+ /// Gets or sets a value indicating whether the API is deprecated.
+ ///
+ /// True if the API deprecated; otherwise, false. The default value is false.
+ public bool IsDeprecated { get; set; }
}
```

## Usage Examples

### Default Behavior

The presence of `ObsoleteAttribute` on a valid action would set `ApiDescription.IsDeprecated` to `true`.

**Default Action (Not Deprecated)**
```c#
[HttpGet]
public IActionResult Get() => Ok();
```

**Deprecated Action**
```c#
[Obsolete, HttpGet]
public IActionResult Get() => Ok();
```

**Non-Action (Ignored)**
```c#
[Obsolete, NonAction, HttpGet]
public override IActionResult Get() => NotImplemented();
```

**Deprecated Controller**
```c#
[Obsolete]
[Route("[controller]")]
public class ValuesController : ControllerBase
{
[HttpGet]
public IActionResult Get() => Ok();
}
```

**Non-Action on Deprecated Controller (Ignored)**
```c#
[Obsolete]
[Route("[controller]")]
public class Values2Controller : ValuesController
{
[NonAction]
[HttpGet]
public override IActionResult Get() => NotImplemented();
}
```

### API Versioning Behavior

The API Versioning extensions for the API Explorer will set `ApiDescription.IsDeprecated` to `true` when
a known, deprecated API version is encountered.

```c#
var builder = WebApplication.CreateBuilder( args );
var app = builder.Build();
var orders = app.NewApiVersionSet( "Orders" ).Build();

app.MapGet( "/orders/{id:int}", ( int id ) => new Order() { Id = id, Customer = "John Doe" } )
.Produces()
.Produces( 404 )
.WithApiVersionSet( orders )
.HasDeprecatedApiVersion( 0.9 )
.HasApiVersion( 1.0 );
```

## Alternative Designs

_Minimal APIs_ have exposed an extension method to set the OpenAPI metadata, but this approach is no different than using an OpenAPI extension in Swashbuckle, NSwag, and so on or simply using OpenAPI .NET directly.

## Risks

There are no tangible risks. The default behavior will continue to indicate that an API is not deprecated by default. Library will authors will be required to update this information when appropriate and consumers will be obliged to honor the value when set.

## Related Links

- #35091
- domaindrivendev/Swashbuckle.AspNetCore#412
- [Omit Obsolete Operations and/or Schema Properties (Swashbuckle)](https://github.com/domaindrivendev/Swashbuckle.AspNetCore#omit-obsolete-operations-andor-schema-properties)

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.