Skip to content

Commit 93bd8dc

Browse files
Add OpenAPI example for Minimal APIs
1 parent efd523e commit 93bd8dc

File tree

13 files changed

+707
-0
lines changed

13 files changed

+707
-0
lines changed

Diff for: asp.sln

+7
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ODataOpenApiExample", "exam
185185
EndProject
186186
Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "Common.OData.ApiExplorer.Tests", "src\Common\test\Common.OData.ApiExplorer.Tests\Common.OData.ApiExplorer.Tests.shproj", "{496A5B79-AFD2-45AC-AF9A-1CD28A7E1CDB}"
187187
EndProject
188+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MinimalOpenApiExample", "examples\AspNetCore\WebApi\MinimalOpenApiExample\MinimalOpenApiExample.csproj", "{124C18D1-F72A-4380-AE40-E7511AC16C62}"
189+
EndProject
188190
Global
189191
GlobalSection(SharedMSBuildProjectFiles) = preSolution
190192
src\Common\test\Common.Acceptance.Tests\Common.Acceptance.Tests.projitems*{0be9efaa-3627-46fe-9861-9121ee8f0e26}*SharedItemsImports = 5
@@ -400,6 +402,10 @@ Global
400402
{B39C3FE5-227F-4403-B246-1277906ACF7D}.Debug|Any CPU.Build.0 = Debug|Any CPU
401403
{B39C3FE5-227F-4403-B246-1277906ACF7D}.Release|Any CPU.ActiveCfg = Release|Any CPU
402404
{B39C3FE5-227F-4403-B246-1277906ACF7D}.Release|Any CPU.Build.0 = Release|Any CPU
405+
{124C18D1-F72A-4380-AE40-E7511AC16C62}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
406+
{124C18D1-F72A-4380-AE40-E7511AC16C62}.Debug|Any CPU.Build.0 = Debug|Any CPU
407+
{124C18D1-F72A-4380-AE40-E7511AC16C62}.Release|Any CPU.ActiveCfg = Release|Any CPU
408+
{124C18D1-F72A-4380-AE40-E7511AC16C62}.Release|Any CPU.Build.0 = Release|Any CPU
403409
EndGlobalSection
404410
GlobalSection(SolutionProperties) = preSolution
405411
HideSolutionNode = FALSE
@@ -481,6 +487,7 @@ Global
481487
{BEF5739D-7E87-4D2A-B3E8-958CBFE16DE0} = {49EA6476-901C-4D4F-8E45-98BC8A2780EB}
482488
{B39C3FE5-227F-4403-B246-1277906ACF7D} = {49EA6476-901C-4D4F-8E45-98BC8A2780EB}
483489
{496A5B79-AFD2-45AC-AF9A-1CD28A7E1CDB} = {031927C1-BF12-42A9-A91D-6907E8C7F1C7}
490+
{124C18D1-F72A-4380-AE40-E7511AC16C62} = {E0E64F6F-FB0C-4534-B815-2217700B50BA}
484491
EndGlobalSection
485492
GlobalSection(ExtensibilityGlobals) = postSolution
486493
SolutionGuid = {91FE116A-CEFB-4304-A8A6-CFF021C7453A}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
namespace ApiVersioning.Examples;
2+
3+
using Asp.Versioning;
4+
using Asp.Versioning.ApiExplorer;
5+
using Microsoft.Extensions.DependencyInjection;
6+
using Microsoft.Extensions.Options;
7+
using Microsoft.OpenApi.Models;
8+
using Swashbuckle.AspNetCore.SwaggerGen;
9+
using System.Text;
10+
11+
/// <summary>
12+
/// Configures the Swagger generation options.
13+
/// </summary>
14+
/// <remarks>This allows API versioning to define a Swagger document per API version after the
15+
/// <see cref="IApiVersionDescriptionProvider"/> service has been resolved from the service container.</remarks>
16+
public class ConfigureSwaggerOptions : IConfigureOptions<SwaggerGenOptions>
17+
{
18+
private readonly IApiVersionDescriptionProvider provider;
19+
20+
/// <summary>
21+
/// Initializes a new instance of the <see cref="ConfigureSwaggerOptions"/> class.
22+
/// </summary>
23+
/// <param name="provider">The <see cref="IApiVersionDescriptionProvider">provider</see> used to generate Swagger documents.</param>
24+
public ConfigureSwaggerOptions( IApiVersionDescriptionProvider provider ) => this.provider = provider;
25+
26+
/// <inheritdoc />
27+
public void Configure( SwaggerGenOptions options )
28+
{
29+
// add a swagger document for each discovered API version
30+
// note: you might choose to skip or document deprecated API versions differently
31+
foreach ( var description in provider.ApiVersionDescriptions )
32+
{
33+
options.SwaggerDoc( description.GroupName, CreateInfoForApiVersion( description ) );
34+
}
35+
}
36+
37+
private static OpenApiInfo CreateInfoForApiVersion( ApiVersionDescription description )
38+
{
39+
var text = new StringBuilder( "An example application with OpenAPI, Swashbuckle, and API versioning." );
40+
var info = new OpenApiInfo()
41+
{
42+
Title = "Example API",
43+
Version = description.ApiVersion.ToString(),
44+
Contact = new OpenApiContact() { Name = "Bill Mei", Email = "[email protected]" },
45+
License = new OpenApiLicense() { Name = "MIT", Url = new Uri( "https://opensource.org/licenses/MIT" ) }
46+
};
47+
48+
if ( description.IsDeprecated )
49+
{
50+
text.Append( " This API version has been deprecated." );
51+
}
52+
53+
if ( description.SunsetPolicy is SunsetPolicy policy )
54+
{
55+
if ( policy.Date is DateTimeOffset when )
56+
{
57+
text.Append( " The API will be sunset on " )
58+
.Append( when.Date.ToShortDateString() )
59+
.Append( '.' );
60+
}
61+
62+
if ( policy.HasLinks )
63+
{
64+
text.AppendLine();
65+
66+
for ( var i = 0; i < policy.Links.Count; i++ )
67+
{
68+
var link = policy.Links[i];
69+
70+
if ( link.Type == "text/html" )
71+
{
72+
text.AppendLine();
73+
74+
if ( link.Title.HasValue )
75+
{
76+
text.Append( link.Title.Value ).Append( ": " );
77+
}
78+
79+
text.Append( link.LinkTarget.OriginalString );
80+
}
81+
}
82+
}
83+
}
84+
85+
info.Description = text.ToString();
86+
87+
return info;
88+
}
89+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<Project Sdk="Microsoft.NET.Sdk.Web">
2+
3+
<PropertyGroup>
4+
<TargetFramework>net6.0</TargetFramework>
5+
</PropertyGroup>
6+
7+
<ItemGroup>
8+
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.3.0-*" />
9+
</ItemGroup>
10+
11+
<ItemGroup>
12+
<ProjectReference Include="..\..\..\..\src\AspNetCore\WebApi\src\Asp.Versioning.Mvc.ApiExplorer\Asp.Versioning.Mvc.ApiExplorer.csproj" />
13+
</ItemGroup>
14+
15+
</Project>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
namespace ApiVersioning.Examples.Models.V1;
2+
3+
using System.ComponentModel.DataAnnotations;
4+
5+
/// <summary>
6+
/// Represents an order.
7+
/// </summary>
8+
public class Order
9+
{
10+
/// <summary>
11+
/// Gets or sets the unique identifier for the order.
12+
/// </summary>
13+
/// <value>The order's unique identifier.</value>
14+
public int Id { get; set; }
15+
16+
/// <summary>
17+
/// Gets or sets the date and time when the order was created.
18+
/// </summary>
19+
/// <value>The order's creation date.</value>
20+
public DateTimeOffset CreatedDate { get; set; } = DateTimeOffset.Now;
21+
22+
/// <summary>
23+
/// Gets or sets the name of the ordering customer.
24+
/// </summary>
25+
/// <value>The name of the customer that placed the order.</value>
26+
[Required]
27+
public string Customer { get; set; }
28+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
namespace ApiVersioning.Examples.Models.V1;
2+
3+
using System.ComponentModel.DataAnnotations;
4+
5+
/// <summary>
6+
/// Represents a person.
7+
/// </summary>
8+
public class Person
9+
{
10+
/// <summary>
11+
/// Gets or sets the unique identifier for a person.
12+
/// </summary>
13+
/// <value>The person's unique identifier.</value>
14+
public int Id { get; set; }
15+
16+
/// <summary>
17+
/// Gets or sets the first name of a person.
18+
/// </summary>
19+
/// <value>The person's first name.</value>
20+
[Required]
21+
[StringLength( 25 )]
22+
public string FirstName { get; set; }
23+
24+
/// <summary>
25+
/// Gets or sets the last name of a person.
26+
/// </summary>
27+
/// <value>The person's last name.</value>
28+
[Required]
29+
[StringLength( 25 )]
30+
public string LastName { get; set; }
31+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
namespace ApiVersioning.Examples.Models.V2;
2+
3+
using System.ComponentModel.DataAnnotations;
4+
5+
/// <summary>
6+
/// Represents an order.
7+
/// </summary>
8+
public class Order
9+
{
10+
/// <summary>
11+
/// Gets or sets the unique identifier for the order.
12+
/// </summary>
13+
/// <value>The order's unique identifier.</value>
14+
public int Id { get; set; }
15+
16+
/// <summary>
17+
/// Gets or sets the date and time when the order was created.
18+
/// </summary>
19+
/// <value>The order's creation date.</value>
20+
public DateTimeOffset CreatedDate { get; set; } = DateTimeOffset.Now;
21+
22+
/// <summary>
23+
/// Gets or sets the date and time when the order becomes effective.
24+
/// </summary>
25+
/// <value>The order's effective date.</value>
26+
public DateTimeOffset EffectiveDate { get; set; } = DateTimeOffset.Now;
27+
28+
/// <summary>
29+
/// Gets or sets the name of the ordering customer.
30+
/// </summary>
31+
/// <value>The name of the customer that placed the order.</value>
32+
[Required]
33+
public string Customer { get; set; }
34+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
namespace ApiVersioning.Examples.Models.V2;
2+
3+
using System.ComponentModel.DataAnnotations;
4+
5+
/// <summary>
6+
/// Represents a person.
7+
/// </summary>
8+
public class Person
9+
{
10+
/// <summary>
11+
/// Gets or sets the unique identifier for a person.
12+
/// </summary>
13+
/// <value>The person's unique identifier.</value>
14+
public int Id { get; set; }
15+
16+
/// <summary>
17+
/// Gets or sets the first name of a person.
18+
/// </summary>
19+
/// <value>The person's first name.</value>
20+
[Required]
21+
[StringLength( 25 )]
22+
public string FirstName { get; set; }
23+
24+
/// <summary>
25+
/// Gets or sets the last name of a person.
26+
/// </summary>
27+
/// <value>The person's last name.</value>
28+
[Required]
29+
[StringLength( 25 )]
30+
public string LastName { get; set; }
31+
32+
/// <summary>
33+
/// Gets or sets the email address for a person.
34+
/// </summary>
35+
/// <value>The person's email address.</value>
36+
public string Email { get; set; }
37+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
namespace ApiVersioning.Examples.Models.V3;
2+
3+
using System.ComponentModel.DataAnnotations;
4+
5+
/// <summary>
6+
/// Represents an order.
7+
/// </summary>
8+
public class Order
9+
{
10+
/// <summary>
11+
/// Gets or sets the unique identifier for the order.
12+
/// </summary>
13+
/// <value>The order's unique identifier.</value>
14+
public int Id { get; set; }
15+
16+
/// <summary>
17+
/// Gets or sets the date and time when the order was created.
18+
/// </summary>
19+
/// <value>The order's creation date.</value>
20+
public DateTimeOffset CreatedDate { get; set; } = DateTimeOffset.Now;
21+
22+
/// <summary>
23+
/// Gets or sets the date and time when the order becomes effective.
24+
/// </summary>
25+
/// <value>The order's effective date.</value>
26+
public DateTimeOffset EffectiveDate { get; set; } = DateTimeOffset.Now;
27+
28+
/// <summary>
29+
/// Gets or sets the name of the ordering customer.
30+
/// </summary>
31+
/// <value>The name of the customer that placed the order.</value>
32+
[Required]
33+
public string Customer { get; set; }
34+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
namespace ApiVersioning.Examples.Models.V3;
2+
3+
using System.ComponentModel.DataAnnotations;
4+
5+
/// <summary>
6+
/// Represents a person.
7+
/// </summary>
8+
public class Person
9+
{
10+
/// <summary>
11+
/// Gets or sets the unique identifier for a person.
12+
/// </summary>
13+
/// <value>The person's unique identifier.</value>
14+
public int Id { get; set; }
15+
16+
/// <summary>
17+
/// Gets or sets the first name of a person.
18+
/// </summary>
19+
/// <value>The person's first name.</value>
20+
[Required]
21+
[StringLength( 25 )]
22+
public string FirstName { get; set; }
23+
24+
/// <summary>
25+
/// Gets or sets the last name of a person.
26+
/// </summary>
27+
/// <value>The person's last name.</value>
28+
[Required]
29+
[StringLength( 25 )]
30+
public string LastName { get; set; }
31+
32+
/// <summary>
33+
/// Gets or sets the email address for a person.
34+
/// </summary>
35+
/// <value>The person's email address.</value>
36+
public string Email { get; set; }
37+
38+
/// <summary>
39+
/// Gets or sets the telephone number for a person.
40+
/// </summary>
41+
/// <value>The person's telephone number.</value>
42+
public string Phone { get; set; }
43+
}

0 commit comments

Comments
 (0)