-
-
Save dj-nitehawk/fbefbcb6273d372e5e5913accb18ab76 to your computer and use it in GitHub Desktop.
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"); | |
} | |
} |
@VictorioBerra it's an extension method overload coming from using Asp.Versioning.Conventions;
Say you are building a HATEOAS API.
I was using ResponseMapper but building the "Links" to append to the response. I am unsure of the best way to get the API Version to append to the end of the link.
links.Add(
new Link
{
Rel = "cancel",
Href = $"/api/jobs/{trackingId}/cancel",
Method = "POST",
}
);
For example, I need to add v1
or v#
to the end. Maybe I should have the ReponseMapper do the basic mapping and add the links later in the actual endpoint instead of using SendMappedAsync
then I have access to the Definition.Version.Current. Is that the best solution or am I not seeing something?
Or maybe the answer is don't build a HATEOAS API 🤣
@byte2pixel
i wouldn't recommend HATEOAS to my worst enemy 😜 (there's a reason why it's not the defacto in the industry)
if you just need route based versioning, stick to one of the built-in versioning strategies.
appending of the version number is the default there:
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.
I think
HasApiVersion(...)
should beHasApiVersion(new(...))