1. API Versioning

API Versioning

The versioning strategy in FastEndpoints is simplified to require way less effort by the developer.

Basically, you evolve/version each endpoint in your project independently and group them into a release number/name using Swagger.

When it's time for an endpoint contract to change, simply leave the existing endpoint alone and create (either by inheriting the old one) or creating a brand new endpoint class and call the Version(x) method in the configuration to indicate that this is the latest incarnation of the endpoint.

For example, let's assume the following:

Initial State

Your app has the following endpoints:

/admin/login
/inventory/order/{OrderID}

After Evolving an Endpoint

/admin/login
/admin/login/v1
/inventory/order/{OrderID}

At this point you can have 2 releases (Swagger documents) that look like the following:

 - initial release
 |- /admin/login
 |- /inventory/order/{OrderID}

 - release 1.0
 |- /admin/login/v1
 |- /inventory/order/{OrderID}

After Another Change

- /admin/login
- /admin/login/v1
- /admin/login/v2
- /inventory/order/{OrderID}
- /inventory/order/{OrderID}/v1

Your releases can now look like this:

 - initial release
 |- /admin/login
 |- /inventory/order/{OrderID}

 - release 1.0
 |- /admin/login/v1
 |- /inventory/order/{OrderID}

 - release 2.0
 |- /admin/login/v2
 |- /inventory/order/{OrderID}/v1

A release group contains only the latest iteration of each endpoint in your project. All older/previous iterations will not show up. How to define release groups is described below.

Enable Versioning

Simply specify one of the VersioningOptions settings in startup config in order to activate versioning.

app.UseFastEndpoints(c =>
{
    c.VersioningOptions = o => o.Prefix = "v";
});

Define Swagger Release Groups

Program.cs
builder.Services.AddSwaggerDoc(s =>
    {
        s.DocumentName = "Initial Release";
        s.Title = "my api";
        s.Version = "v1.0";
    })
    .AddSwaggerDoc(maxEndpointVersion: 1, settings: s =>
    {
        s.DocumentName = "Release 1.0";
        s.Title = "my api";
        s.Version = "v1.0";
    })
    .AddSwaggerDoc(maxEndpointVersion: 2, settings: s =>
    {
        s.DocumentName = "Release 2.0";
        s.Title = "my api";
        s.Version = "v2.0";
    });

The thing to note here is the maxEndpointVersion parameter. This is where you specify the max version of an endpoint which a release group should include.

Any endpoint versions that are greater than this number will not be included in that release group/swagger doc.

If you don't specify this, only the initial version of each endpoint will be listed in the group.

Mark Endpoint With a Version

public class AdminLoginEndpoint_V2 : Endpoint<Request>
{
    public override void Configure()
    {
        Get("admin/login");
        Version(2);
    }
}

Deprecate an Endpoint

You can specify that an endpoint should not be visible after (and including) a given version group like so:

Version(1, deprecateAt: 4);

An endpoint marked as above will be visible in all swagger docs up until maxEndpointVersion : 4. it will be excluded from docs starting from 4 and above. as an example, take to following two endpoints.

Initial release

/user/delete
/user/profile

Release Group v1.0

/user/delete/v1
/user/profile/v1

Release Group v2.0

/user/delete/v1
/user/profile/v2

If you mark the /user/delete/v1 endpoint with Version(1, deprecateAt: 2) then release groups v2.0 and newer will not have any /user/delete endpoints listed.

And the release will look like this:

release group v2.0

/user/profile/v2

It is only necessary to mark the last endpoint version as deprecated. You can leave all previous iterations alone, if there's any.

Versioning Options

At least one of the following settings should be set in order to enable versioning support.

  • Prefix : A string to be used in front of the version (for example 'v' produces 'v1')

  • DefaultVersion : This value will be used for endpoints that do not specify a version in it's configuration. The default value is 0. When the version of an endpoint is 0 it does not get added to the route making that version the initial version of that endpoint.

  • SuffixedVersion : By default the version string is appended to the endpoint route. By setting this to false, you can have it prepended to the route.


© FastEndpoints 2022