Skip to content

Commit 9b4f943

Browse files
authored
Update to Asp.Versioning to v10-preview2 (#980)
1 parent b81ad95 commit 9b4f943

9 files changed

Lines changed: 74 additions & 46 deletions

File tree

.spectral.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
extends: spectral:oas
22
rules:
33
info-contact: off
4+
oas3-api-servers: off
45

56
success-response:
67
description: All operations should have a success response.

Directory.Packages.props

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
<AspireUnstablePackagesVersion>13.2.0-preview.1.26170.3</AspireUnstablePackagesVersion>
99
<GrpcVersion>2.76.0</GrpcVersion>
1010
<DuendeVersion>7.3.1</DuendeVersion>
11-
<ApiVersioningVersion>8.1.0</ApiVersioningVersion>
11+
<ApiVersioningVersion>10.0.0-preview.2</ApiVersioningVersion>
1212
</PropertyGroup>
1313
<ItemGroup>
1414
<!-- Version together with Aspire -->
@@ -26,6 +26,7 @@
2626
<PackageVersion Include="Asp.Versioning.Http" Version="$(ApiVersioningVersion)" />
2727
<PackageVersion Include="Asp.Versioning.Http.Client" Version="$(ApiVersioningVersion)" />
2828
<PackageVersion Include="Asp.Versioning.Mvc.ApiExplorer" Version="$(ApiVersioningVersion)" />
29+
<PackageVersion Include="Asp.Versioning.OpenApi" Version="$(ApiVersioningVersion)" />
2930
<!-- Version together with ASP.NET -->
3031
<PackageVersion Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="$(DotnetPackagesVersion)" />
3132
<PackageVersion Include="Microsoft.AspNetCore.Authentication.OpenIdConnect" Version="$(DotnetPackagesVersion)" />
@@ -93,4 +94,4 @@
9394
<!-- Before license change -->
9495
<PackageVersion Include="MediatR" Version="13.0.0" />
9596
</ItemGroup>
96-
</Project>
97+
</Project>

src/Catalog.API/Catalog.API.http

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,45 @@
1-
@Catalog.API_HostAddress = http://localhost:5222
1+
@HostAddress = http://localhost:5222
22
@ApiVersion = 1.0
33

4-
GET {{Catalog.API_HostAddress}}/openapi/v1.json
4+
GET {{HostAddress}}/openapi/v1.json
55

66
###
77

8-
GET {{Catalog.API_HostAddress}}/api/catalog/items?api-version={{ApiVersion}}
8+
GET {{HostAddress}}/openapi/v2.json
99

1010
###
1111

12-
GET {{Catalog.API_HostAddress}}/api/catalog/items/type/1/brand/2?api-version={{ApiVersion}}
12+
# Scalar: http://localhost:5222/scalar/v1
13+
14+
###
15+
16+
# api-version is required, so this request will fail
17+
18+
GET {{HostAddress}}/api/catalog/items
19+
20+
###
21+
22+
GET {{HostAddress}}/api/catalog/items?api-version={{ApiVersion}}
23+
24+
###
25+
26+
GET {{HostAddress}}/api/catalog/items/type/1/brand/2?api-version={{ApiVersion}}
1327

1428
###
1529

1630
# A request with an unknown API version returns a 400 ProblemDetails response
1731

18-
GET {{Catalog.API_HostAddress}}/api/catalog/items/463/pic?api-version=99
32+
GET {{HostAddress}}/api/catalog/items/463/pic?api-version=99
1933

2034
###
2135

2236
# A request with an unknown item id returns a 404 NotFound with empty response body
2337

24-
GET {{Catalog.API_HostAddress}}/api/catalog/items/463/pic?api-version={{ApiVersion}}
38+
GET {{HostAddress}}/api/catalog/items/463/pic?api-version={{ApiVersion}}
2539

2640
###
2741

28-
PUT {{Catalog.API_HostAddress}}/api/catalog/items?api-version={{ApiVersion}}
42+
PUT {{HostAddress}}/api/catalog/items?api-version={{ApiVersion}}
2943
content-type: application/json
3044

3145
{

src/Catalog.API/Program.cs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
1-
using Asp.Versioning.Builder;
2-
using System.Reflection;
3-
4-
var builder = WebApplication.CreateBuilder(args);
1+
var builder = WebApplication.CreateBuilder(args);
52

63
builder.AddServiceDefaults();
74
builder.AddApplicationServices();
85
builder.Services.AddProblemDetails();
96

10-
var withApiVersioning = builder.Services.AddApiVersioning();
7+
var withApiVersioning = builder.Services.AddApiVersioning(options =>
8+
{
9+
// Include "api-supported-versions" and "api-deprecated-versions" headers in all responses
10+
options.ReportApiVersions = true;
11+
});
1112

1213
builder.AddDefaultOpenApi(withApiVersioning);
1314

src/Ordering.API/Program.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,11 @@
44
builder.AddApplicationServices();
55
builder.Services.AddProblemDetails();
66

7-
var withApiVersioning = builder.Services.AddApiVersioning();
7+
var withApiVersioning = builder.Services.AddApiVersioning(options =>
8+
{
9+
// Include "api-supported-versions" and "api-deprecated-versions" headers in all responses
10+
options.ReportApiVersions = true;
11+
});
812

913
builder.AddDefaultOpenApi(withApiVersioning);
1014

src/Webhooks.API/Program.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,11 @@
33
builder.AddServiceDefaults();
44
builder.AddApplicationServices();
55

6-
var withApiVersioning = builder.Services.AddApiVersioning();
6+
var withApiVersioning = builder.Services.AddApiVersioning(options =>
7+
{
8+
// Include "api-supported-versions" and "api-deprecated-versions" headers in all responses
9+
options.ReportApiVersions = true;
10+
});
711

812
builder.AddDefaultOpenApi(withApiVersioning);
913

src/eShop.ServiceDefaults/OpenApi.Extensions.cs

Lines changed: 23 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -21,16 +21,24 @@ public static IApplicationBuilder UseDefaultOpenApi(this WebApplication app)
2121
return app;
2222
}
2323

24-
app.MapOpenApi();
24+
app.MapOpenApi().WithDocumentPerVersion();
2525

2626
if (app.Environment.IsDevelopment())
2727
{
28+
var descriptions = app.DescribeApiVersions();
29+
var defaultDocument = descriptions.Count > 0 ? descriptions[^1].GroupName : "v1";
30+
2831
app.MapScalarApiReference(options =>
2932
{
3033
// Disable default fonts to avoid download unnecessary fonts
3134
options.DefaultFonts = false;
35+
36+
foreach (var description in descriptions)
37+
{
38+
options.AddDocument(description.GroupName, description.GroupName, isDefault: description.GroupName == defaultDocument);
39+
}
3240
});
33-
app.MapGet("/", () => Results.Redirect("/scalar/v1")).ExcludeFromDescription();
41+
app.MapGet("/", () => Results.Redirect($"/scalar/{defaultDocument}")).ExcludeFromDescription();
3442
}
3543

3644
return app;
@@ -57,19 +65,21 @@ public static IHostApplicationBuilder AddDefaultOpenApi(
5765
{
5866
// the default format will just be ApiVersion.ToString(); for example, 1.0.
5967
// this will format the version as "'v'major[.minor][-status]"
60-
var versioned = apiVersioning.AddApiExplorer(options => options.GroupNameFormat = "'v'VVV");
61-
string[] versions = ["v1", "v2"];
62-
foreach (var description in versions)
63-
{
64-
builder.Services.AddOpenApi(description, options =>
68+
apiVersioning.AddApiExplorer(options =>
69+
{
70+
options.GroupNameFormat = "'v'VVV";
71+
options.DefaultApiVersionParameterDescription = "The API version, in the format 'major.minor'.";
72+
})
73+
.AddOpenApi(options =>
6574
{
66-
options.ApplyApiVersionInfo(openApi.GetRequiredValue("Document:Title"), openApi.GetRequiredValue("Document:Description"));
67-
options.ApplyAuthorizationChecks([.. scopes.Keys]);
68-
options.ApplySecuritySchemeDefinitions();
69-
options.ApplyOperationDeprecatedStatus();
70-
options.ApplyApiVersionDescription();
75+
var document = options.Document;
76+
77+
document.ApplyApiVersionInfo(openApi.GetRequiredValue("Document:Title"), openApi.GetRequiredValue("Document:Description"));
78+
document.ApplyAuthorizationChecks([.. scopes.Keys]);
79+
document.ApplySecuritySchemeDefinitions();
80+
document.ApplyOperationDeprecatedStatus();
81+
document.ApplyApiVersionDescription();
7182
});
72-
}
7383
}
7484

7585
return builder;

src/eShop.ServiceDefaults/OpenApiOptionsExtensions.cs

Lines changed: 9 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -139,8 +139,10 @@ public static OpenApiOptions ApplyOperationDeprecatedStatus(this OpenApiOptions
139139
{
140140
options.AddOperationTransformer((operation, context, cancellationToken) =>
141141
{
142-
var apiDescription = context.Description;
143-
operation.Deprecated |= apiDescription.IsDeprecated();
142+
operation.Deprecated = operation.Deprecated || context.Description.ActionDescriptor.EndpointMetadata
143+
.OfType<ObsoleteAttribute>()
144+
.Any();
145+
144146
return Task.CompletedTask;
145147
});
146148
return options;
@@ -150,22 +152,12 @@ public static OpenApiOptions ApplyApiVersionDescription(this OpenApiOptions opti
150152
{
151153
options.AddOperationTransformer((operation, context, cancellationToken) =>
152154
{
153-
// Find parameter named "api-version" and add a description to it
155+
// Add an example for the API version parameter and remove the default value
154156
var apiVersionParameter = operation.Parameters?.FirstOrDefault(p => p.Name == "api-version");
155-
if (apiVersionParameter is not null)
157+
if (apiVersionParameter?.Schema is OpenApiSchema targetSchema)
156158
{
157-
apiVersionParameter.Description = "The API version, in the format 'major.minor'.";
158-
if (apiVersionParameter.Schema is OpenApiSchema targetSchema)
159-
{
160-
switch (context.DocumentName) {
161-
case "v1":
162-
targetSchema.Example = JsonNode.Parse("\"1.0\"");
163-
break;
164-
case "v2":
165-
targetSchema.Example = JsonNode.Parse("\"2.0\"");
166-
break;
167-
}
168-
}
159+
targetSchema.Example = targetSchema.Default;
160+
targetSchema.Default = null;
169161
}
170162
return Task.CompletedTask;
171163
});
@@ -199,7 +191,7 @@ public Task TransformAsync(OpenApiDocument document, OpenApiDocumentTransformerC
199191
}
200192
};
201193
document.Components ??= new();
202-
document.Components.SecuritySchemes ??= new Dictionary<string, IOpenApiSecurityScheme>();
194+
document.Components.SecuritySchemes ??= new Dictionary<string, IOpenApiSecurityScheme>();
203195
document.Components.SecuritySchemes.Add("oauth2", securityScheme);
204196
return Task.CompletedTask;
205197
}

src/eShop.ServiceDefaults/eShop.ServiceDefaults.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
<ItemGroup>
1313
<PackageReference Include="Asp.Versioning.Mvc.ApiExplorer" />
14+
<PackageReference Include="Asp.Versioning.OpenApi" />
1415
<PackageReference Include="Microsoft.AspNetCore.OpenApi" />
1516
<PackageReference Include="Microsoft.OpenApi" />
1617
<PackageReference Include="Scalar.AspNetCore" />

0 commit comments

Comments
 (0)