Skip to content

6.2.0

Compare
Choose a tag to compare
@commonsensesoftware commonsensesoftware released this 08 Nov 04:03
· 161 commits to main since this release

This is a minor release which contains mostly fixes and a few new enhancements. The next phase in the roadmap will be supporting .NET 7.0.

.NET Core 3.1 will be End of Life in December of 2022; therefore, support for that target framework will be dropped in the next major release. With the exception of servicing for bug fixes, this will be the last release for .NET Core 3.1.

Features

Abstractions

  • Added ApiVersionMetadata copy constructor

All Platforms

  • Add complex media type API version reader support (#887)

ASP.NET Web API

  • Type-forward route parsing from API Explorer to core library

ASP.NET Web API with OData

  • Add support for exploring OData metadata routes (#893)

ASP.NET Core

  • Support 406 and 415 with ProblemDetails (#886)
  • Handle missing ApiVersionMetadata (#891)
  • Handle multiple SelectorModel instances (#896)
  • Add IApiVersionDescriptionProviderFactory (enables DI within DescribeApiVersions)
  • Add support for custom group name formatting

ASP.NET Core with OData

  • Add support for exploring OData metadata routes (#893)

New Feature Preview

Enhanced Media Type Reader

The new MediaTypeApiVersionReaderBuilder has compositional support with the following features:

  • Multiple parameters (if they vary by media type)
  • Including specific media types
  • Excluding specific media types
  • Matching a version in a media type by regular expression (it's an escape hatch really)
  • Matching a version in a media type by a template
  • Disambiguate from multiple choices

Here's a basic example:

var builder = new MediaTypeApiVersionReaderBuilder()
var reader = builder
    .Parameter( "v" )
    .Include( "application/json" )
    .Include( "application/xml" )
    .Template( "application/vnd-v{ver}+json" )
    .Template( "application/vnd-v{ver}+xml" )
    .Build();

This will match:

  • A parameter named v on any media type filtered to:
    • application/json
    • application/xml
  • A media type matching the template application/vnd-v{ver}+json where ver is the user-defined parameter name
  • A media type matching the template application/vnd-v{ver}+xml where ver is the user-defined parameter name

Composite Group Names

The API Explorer and OpenAPI (aka Swagger) UI do not support multi-level grouping. Implementing some form of this
has been possible, but complex in the past. API Versioning uses a formatted API version as the group name as a
logical choice, but some people want to combine that with a group name. A new feature will give you the option
to format a group name and API version together.

services.AddApiVersioning()
        .AddApiExplorer( options =>
        {
          options.GroupNameFormat = "'v'VVV";
          options.FormatGroupName = (groupName, apiVersion) => $"{groupName}-{apiVersion}";
        });

There are multiple ways to define a group name, but a controller might look like:

[ApiVersion( 1.0 )]
[ApiController]
[ApiExplorerSettings( GroupName = "Example" )]
[Route( "[controller]" )]
public class ExampleController : ControllerBase
{
  [HttpGet]
  public IActionResult Get() => Ok();
}

The formatting rules are as follows:

  • ApiVersion.ToString( ApiExplorerOptions.GroupNameFormat ) is the default group name
  • If a group name is defined and ApiExplorerOptions.FormatGroupName is null, the group name is used
  • If a group name is defined and ApiExplorerOptions.FormatGroupName is not null, the callback is invoked with the group name and formatted API version
  • If a group name is not defined, then the formatted API version is used

In the example above, the final group name will become Example-v1.

OData Metadata Endpoints

OData has a built-in Service Document and Metadata endpoint. These largely serve the same purpose as OpenAPI (aka Swagger) in
days gone by. You might, however, still want these to show up. The default will continue to keep them hidden, but you can now enable
showing one or both of them via:

services.AddControllers().AddOData();

services.AddApiVersioning()
        .AddOData( options => options.AddRouteComponents() )
        .AddODataApiExplorer( options.MetadataOptions = ODataMetadataOptions.All );

Breaking Changes

No known breaking changes

Contributors

Thanks you to all that contributed directly with code, filling issues, and in-depth discussions. In particular, special thanks to: