Skip to content

10.2.0

Latest

Choose a tag to compare

@commonsensesoftware commonsensesoftware released this 06 Aug 04:51

This release includes some big new features but is fully backward compatible with 10.0.0. The new features include versioned model member filtering, Roslyn analyzers, gRPC preview support, and a number of servicing patches since the previous release.

Fixes

All Platforms

  • Parsing an API version whose status ends in '.' no longer succeeds silently
  • Very large padding values in a format string no longer cause a stack overflow
  • Incorrect lower and upper bounds when matching API version ranges
  • Parsing a positive integer no longer allows whitespace or a leading '-'

ASP.NET Core

  • Routes are no longer incorrectly evicted from the route table (#1138)
  • Fixed routing of unversioned endpoints
  • Fixed extracting an API version that includes a status when versioning by URL segment (#1187)
  • A user-registered IProblemDetailsWriter is preserved by AddApiVersioning() (#1191)

ASP.NET Core OpenAPI

  • Support for more XML comment tags (#1205)
  • Fixed the error message reported for an unmapped JSON property
  • Fixed descriptions applied to filtered members

Features

All Platforms

  • New ApiVersionRange type for matching a set of API versions using the same interval notation as a package version
    • 1.0x ≥ 1.0
    • [1.0]x == 1.0
    • (1.0,)x > 1.0
    • (,1.0]x ≤ 1.0
    • [1.0,2.0)1.0 ≤ x < 2.0
    • Multiple rules are combined as a logical or; ApiVersionRange.Any and ApiVersionRange.Empty are provided for
      the degenerate cases
    • A range matches API versions; it does not define them. API versions must still be explicitly declared
  • New VisibleInApiVersionAttribute indicates the range of API versions a data member is visible in; for example,
    [VisibleInApiVersion("2.0")]
  • New IAnnotation<TKey, TValue> abstraction for associating out-of-band metadata with a member
  • [StringSyntax] is now applied to API version inputs so the IDE and analyzers understand them; the recognized
    syntaxes are ApiVersion, ApiVersionRange, and ApiVersionFormat

Analyzers

API Versioning now ships Roslyn analyzers. There is no new package to install — the core rules are packed into Asp.Versioning.Abstractions and the API rules are packed into Asp.Versioning.Http, so any application that already references API Versioning picks them up transitively.

There is an initial set of 31 rules. You can find all of the rule information in the new diagnostics wiki topic.

Notes:

  • Every rule has a helpLinkUri that resolves to its documentation page
  • Individual rules can be configured through .editorconfig as usual
  • All analyzers can be turned off with a single MSBuild property:
    <PropertyGroup>
      <EnableApiVersioningAnalyzers>false</EnableApiVersioningAnalyzers>
    </PropertyGroup>
    ExcludeAssets="analyzers" on a PackageReference will not work because the package is also reached through
    the dependencies of other packages and NuGet combines the assets from every path

ASP.NET Web API (Classic) is not currently supported. If there is demand, I will consider the support, but I presume
little new development is happening on the older platform.

ASP.NET Core

Data members can now be versioned independently of the endpoint that returns them. Annotate a property with [VisibleInApiVersion] and the member is omitted from responses for API versions outside the range:

public class Person
{
    public int Id { get; set; }

    public string FirstName { get; set; }

    [VisibleInApiVersion( "2.0" )]
    public Address? HomeAddress { get; set; }

    [VisibleInApiVersion( "[1.0,2.0)" )]
    public string? LegacyEmail { get; set; }
}
  • Works for both Minimal APIs and MVC (Core)
  • Filtering members is currently only support for the JSON media type
  • Filtering applies on the way in as well as the way out, which closes the corresponding over-posting gap
  • AddApiVersioning() now registers IHttpContextAccessor so the requested API version is available during
    serialization
  • [VisibleInApiVersion] is part of the core abstractions and can be used in your model libraries without any
    dependency on ASP.NET

ASP.NET Core API Explorer

  • The API explorer describes only the model members visible in the API version being explored via the new
    VersionedModelMetadata, VersionedModelMetadataProvider, and DelegatingModelMetadata types
  • Only models that are actually explored are filtered for visibility

ASP.NET Core OpenAPI

  • Generated schemas reflect per-version member visibility, so the documented shape of a model matches what the API
    actually returns for that version
  • Significantly expanded XML comment support:
    • <remarks> now takes precedence over <description>
    • <b> and <i> are converted to and retained as Markdown
    • <a href="..."/> is converted to and retained as a hyperlink
    • <paramref name="..."/> is rendered as inline code
    • <list>, <item>, <term>, <description>, <value>, and <example> are supported
    • <inheritdoc/> is resolved for summaries
    • Multi-line code fences from <code> blocks are properly closed

ASP.NET Core with gRPC (Preview)

Two new packages add API Versioning to gRPC services: Asp.Versioning.Grpc and Asp.Versioning.Grpc.ApiExplorer. This is a new set of features that will run in preview to give gRPC service authors a chance to try things out and report any issues or gaps.

The following is a basic example showing all of the parts coming together.

services.AddApiVersioning()
        .AddGrpc()
        .AddGrpcApiExplorer()
        .AddOpenApi();

var people = app.NewVersionedApi( "People" );

people.MapGrpcService<PeopleService>()
      .HasApiVersion( 1.0 )
      .HasApiVersion( 2.0 )
      .HasApiVersion( 3.0 );
  • Services are versioned with the same conventions used everywhere else — a single implementation can support several
    API versions, or implementations can be split across versions
  • Message fields are annotated with the API versions they belong to using the new asp/api/annotations.proto:
    import "asp/api/annotations.proto";
    
    message Person {
        int32 id = 1;
        string first_name = 2;
        string last_name = 3;
        Address home_address = 4 [(asp.api.version) = "2.0"];
        string phone = 5 [(asp.api.version) = "3.0"];
    }
    • The option is repeated, so a field split across disjoint ranges repeats the option
    • A field with no annotation is included in every API version
  • A server interceptor filters fields out of requests and responses — including streaming in both directions — so a
    client on 1.0 can neither see nor post a field that was introduced in 3.0
  • JSON transcoded gRPC services are described by the API explorer and appear in the OpenAPI document with the API
    version route segment and well-known protobuf types mapped to their correct schemas

The gRPC OpenAPI Example demonstrates an end-to-end working solution.

Breaking Changes

All Platforms

  • The analyzers are on by default. They ship inside Asp.Versioning.Abstractions and Asp.Versioning.Http, which
    means upgrading turns them on for every project that references API versioning — directly or transitively. AV0012,
    AV0018, and AV0019 default to error severity, so an existing application that trips one of them will fail to build
    until the underlying problem is fixed, the rule is downgraded in .editorconfig, or
    <EnableApiVersioningAnalyzers>false</EnableApiVersioningAnalyzers> is set. Before these rules existed, an
    application should have either encountered runtime exceptions or not functioned as expected. These rules are catching
    mistakes early rather than imposing specific dogma about how your application must be defined.

ASP.NET Core

  • AddApiVersioning() now calls AddHttpContextAccessor(). This is additive and should be transparent, but it does mean
    IHttpContextAccessor is registered in applications that previously did not have it

Documentation

The wiki has served the community well for many years, but it had gotten tired and it was due for some much needed love and updates. I've reworked the wiki into a new GitHub Pages site using mdBook.

  • The wiki has been ported to GitHub Pages and is now published at dotnet.github.io/aspnet-api-versioning with search, per-page tables of contents, and side-by-side content for each supported flavor of ASP.NET
  • README badges and links throughout the repository now point at the new site
  • The old wiki pages still exist so that old links are not broken
    • All future links should link to the new content

Why change?

  • There was little-to-no control over wiki page names, which makes it difficult for SEO
  • The wiki HTML support is much more limited that GitHub Pages
    • Theming is also supported
  • The wiki was considerable in size, but you couldn't search it; now you can
  • The project started with ASP.NET Web API (Classic) a decade ago, but ASP.NET Core is now the de facto platform
    • ASP.NET Core and Web API (Classic) have been split apart
    • There will be overlap in search, but everything else is cleanly separated
  • Errors and updates. There has never been a good way for the community to create pull requests to update content
  • The content lifecycle was outside of the repository content; now it's side-by-side
    • This helps keep the content current and fresh
  • Printing now has first-class support

It certainly possible that some links or content are incorrect after the migration. Please report any errors or submit a pull request
and they will be fixed promptly.

Release Notes

  • Package release notes are now emitted through the PackageReleaseNotes property instead of being appended to the
    package README (#1211)
  • Asp.Versioning.OData and Asp.Versioning.OpenAPI are no longer rc; both were promoted to stable during servicing and ship as 10.2.0
  • Asp.Versioning.Grpc and Asp.Versioning.Grpc.ApiExplorer are new in this release and ship at 10.2.0-preview.1 alongside everything else
  • Microsoft.OpenApi was updated to 2.7.5 due to a vulnerability and pinned to below 3.0.0 after a major version
    incompatibility

Feedback

Thanks to everyone who contributed to this release, whether through code, issues, or test driving the changes.