Skip to content

Instantly share code, notes, and snippets.

@dj-nitehawk
Last active April 3, 2025 03:37
Show Gist options
  • Save dj-nitehawk/fbefbcb6273d372e5e5913accb18ab76 to your computer and use it in GitHub Desktop.
Save dj-nitehawk/fbefbcb6273d372e5e5913accb18ab76 to your computer and use it in GitHub Desktop.
Asp.Versioning.Http Example
using Asp.Versioning;
using Asp.Versioning.Conventions;
using FastEndpoints;
using FastEndpoints.AspVersioning;
using FastEndpoints.Swagger;
VersionSets.CreateApi(">>Orders<<", v => v
.HasApiVersion(1.0)
.HasApiVersion(2.0));
VersionSets.CreateApi(">>Inventory<<", v =>
{
v.HasApiVersion(1.0);
v.HasApiVersion(1.1);
});
var bld = WebApplication.CreateBuilder();
bld.Services
.AddFastEndpoints()
.AddVersioning(o =>
{
o.DefaultApiVersion = new(1.0);
o.AssumeDefaultVersionWhenUnspecified = true;
o.ApiVersionReader = new HeaderApiVersionReader("X-Api-Version");
})
.SwaggerDocument(o =>
{
o.DocumentSettings = x =>
{
x.DocumentName = "version one";
x.ApiVersion(new(1.0));
};
o.AutoTagPathSegmentIndex = 0;
})
.SwaggerDocument(o =>
{
o.DocumentSettings = x =>
{
x.DocumentName = "version one point one";
x.ApiVersion(new(1.1));
};
o.AutoTagPathSegmentIndex = 0;
})
.SwaggerDocument(o =>
{
o.DocumentSettings = x =>
{
x.DocumentName = "version two";
x.ApiVersion(new(2.0));
};
o.AutoTagPathSegmentIndex = 0;
});
var app = bld.Build();
app.UseFastEndpoints()
.UseSwaggerGen();
app.Run();
public class GetInvoices_v1 : EndpointWithoutRequest
{
public override void Configure()
{
Get("invoices");
AllowAnonymous();
Options(x => x
.WithVersionSet(">>Orders<<")
.MapToApiVersion(1.0));
}
public override async Task HandleAsync(CancellationToken c)
{
await SendAsync("v1 - orders");
}
}
public class GetInvoices_v2 : EndpointWithoutRequest
{
public override void Configure()
{
Get("invoices");
AllowAnonymous();
Options(x => x
.WithVersionSet(">>Orders<<")
.MapToApiVersion(2.0));
}
public override async Task HandleAsync(CancellationToken c)
{
await SendAsync("v2 - orders");
}
}
public class GetStockItems_v1 : EndpointWithoutRequest
{
public override void Configure()
{
Get("stock-items");
AllowAnonymous();
Options(x => x
.WithVersionSet(">>Inventory<<")
.MapToApiVersion(1.0));
}
public override async Task HandleAsync(CancellationToken c)
{
await SendAsync("v1 - inventory");
}
}
public class GetStockItems_v1_1 : EndpointWithoutRequest
{
public override void Configure()
{
Get("stock-items");
AllowAnonymous();
Options(x => x
.WithVersionSet(">>Inventory<<")
.MapToApiVersion(1.1));
}
public override async Task HandleAsync(CancellationToken c)
{
await SendAsync("v1.1 - inventory");
}
}
@byte2pixel
Copy link

Haha ok.
I am not set on it. I opted out of using route-based versioning anyway. The approach above with FastEndpoints.AspVersioning; seems much better.

I also found that LinkGenerator seems to work very well. The only problem I would run into is that I need to probably pass in what version they are using to know what path name to use when calling the method on LinkGenerator.

The more I dig into this the less I am inclined to have these links. The thought seems nice if there is no cancel link the UI doesn't have to show the cancel button, if there is then it can show it and use the href to call if it is pressed.

It is one of those, it seems like it would be nice, but also be very difficult to do it right.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment