Skip to content

Commit

Permalink
Add OpenAPI example for Minimal APIs
Browse files Browse the repository at this point in the history
  • Loading branch information
commonsensesoftware committed Apr 9, 2022
1 parent efd523e commit 93bd8dc
Show file tree
Hide file tree
Showing 13 changed files with 707 additions and 0 deletions.
7 changes: 7 additions & 0 deletions asp.sln
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ODataOpenApiExample", "exam
EndProject
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}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MinimalOpenApiExample", "examples\AspNetCore\WebApi\MinimalOpenApiExample\MinimalOpenApiExample.csproj", "{124C18D1-F72A-4380-AE40-E7511AC16C62}"
EndProject
Global
GlobalSection(SharedMSBuildProjectFiles) = preSolution
src\Common\test\Common.Acceptance.Tests\Common.Acceptance.Tests.projitems*{0be9efaa-3627-46fe-9861-9121ee8f0e26}*SharedItemsImports = 5
Expand Down Expand Up @@ -400,6 +402,10 @@ Global
{B39C3FE5-227F-4403-B246-1277906ACF7D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B39C3FE5-227F-4403-B246-1277906ACF7D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B39C3FE5-227F-4403-B246-1277906ACF7D}.Release|Any CPU.Build.0 = Release|Any CPU
{124C18D1-F72A-4380-AE40-E7511AC16C62}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{124C18D1-F72A-4380-AE40-E7511AC16C62}.Debug|Any CPU.Build.0 = Debug|Any CPU
{124C18D1-F72A-4380-AE40-E7511AC16C62}.Release|Any CPU.ActiveCfg = Release|Any CPU
{124C18D1-F72A-4380-AE40-E7511AC16C62}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down Expand Up @@ -481,6 +487,7 @@ Global
{BEF5739D-7E87-4D2A-B3E8-958CBFE16DE0} = {49EA6476-901C-4D4F-8E45-98BC8A2780EB}
{B39C3FE5-227F-4403-B246-1277906ACF7D} = {49EA6476-901C-4D4F-8E45-98BC8A2780EB}
{496A5B79-AFD2-45AC-AF9A-1CD28A7E1CDB} = {031927C1-BF12-42A9-A91D-6907E8C7F1C7}
{124C18D1-F72A-4380-AE40-E7511AC16C62} = {E0E64F6F-FB0C-4534-B815-2217700B50BA}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {91FE116A-CEFB-4304-A8A6-CFF021C7453A}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
namespace ApiVersioning.Examples;

using Asp.Versioning;
using Asp.Versioning.ApiExplorer;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using Microsoft.OpenApi.Models;
using Swashbuckle.AspNetCore.SwaggerGen;
using System.Text;

/// <summary>
/// Configures the Swagger generation options.
/// </summary>
/// <remarks>This allows API versioning to define a Swagger document per API version after the
/// <see cref="IApiVersionDescriptionProvider"/> service has been resolved from the service container.</remarks>
public class ConfigureSwaggerOptions : IConfigureOptions<SwaggerGenOptions>
{
private readonly IApiVersionDescriptionProvider provider;

/// <summary>
/// Initializes a new instance of the <see cref="ConfigureSwaggerOptions"/> class.
/// </summary>
/// <param name="provider">The <see cref="IApiVersionDescriptionProvider">provider</see> used to generate Swagger documents.</param>
public ConfigureSwaggerOptions( IApiVersionDescriptionProvider provider ) => this.provider = provider;

/// <inheritdoc />
public void Configure( SwaggerGenOptions options )
{
// add a swagger document for each discovered API version
// note: you might choose to skip or document deprecated API versions differently
foreach ( var description in provider.ApiVersionDescriptions )
{
options.SwaggerDoc( description.GroupName, CreateInfoForApiVersion( description ) );
}
}

private static OpenApiInfo CreateInfoForApiVersion( ApiVersionDescription description )
{
var text = new StringBuilder( "An example application with OpenAPI, Swashbuckle, and API versioning." );
var info = new OpenApiInfo()
{
Title = "Example API",
Version = description.ApiVersion.ToString(),
Contact = new OpenApiContact() { Name = "Bill Mei", Email = "bill.mei@somewhere.com" },
License = new OpenApiLicense() { Name = "MIT", Url = new Uri( "https://opensource.org/licenses/MIT" ) }
};

if ( description.IsDeprecated )
{
text.Append( " This API version has been deprecated." );
}

if ( description.SunsetPolicy is SunsetPolicy policy )
{
if ( policy.Date is DateTimeOffset when )
{
text.Append( " The API will be sunset on " )
.Append( when.Date.ToShortDateString() )
.Append( '.' );
}

if ( policy.HasLinks )
{
text.AppendLine();

for ( var i = 0; i < policy.Links.Count; i++ )
{
var link = policy.Links[i];

if ( link.Type == "text/html" )
{
text.AppendLine();

if ( link.Title.HasValue )
{
text.Append( link.Title.Value ).Append( ": " );
}

text.Append( link.LinkTarget.OriginalString );
}
}
}
}

info.Description = text.ToString();

return info;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<Project Sdk="Microsoft.NET.Sdk.Web">

<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.3.0-*" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\..\..\..\src\AspNetCore\WebApi\src\Asp.Versioning.Mvc.ApiExplorer\Asp.Versioning.Mvc.ApiExplorer.csproj" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
namespace ApiVersioning.Examples.Models.V1;

using System.ComponentModel.DataAnnotations;

/// <summary>
/// Represents an order.
/// </summary>
public class Order
{
/// <summary>
/// Gets or sets the unique identifier for the order.
/// </summary>
/// <value>The order's unique identifier.</value>
public int Id { get; set; }

/// <summary>
/// Gets or sets the date and time when the order was created.
/// </summary>
/// <value>The order's creation date.</value>
public DateTimeOffset CreatedDate { get; set; } = DateTimeOffset.Now;

/// <summary>
/// Gets or sets the name of the ordering customer.
/// </summary>
/// <value>The name of the customer that placed the order.</value>
[Required]
public string Customer { get; set; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
namespace ApiVersioning.Examples.Models.V1;

using System.ComponentModel.DataAnnotations;

/// <summary>
/// Represents a person.
/// </summary>
public class Person
{
/// <summary>
/// Gets or sets the unique identifier for a person.
/// </summary>
/// <value>The person's unique identifier.</value>
public int Id { get; set; }

/// <summary>
/// Gets or sets the first name of a person.
/// </summary>
/// <value>The person's first name.</value>
[Required]
[StringLength( 25 )]
public string FirstName { get; set; }

/// <summary>
/// Gets or sets the last name of a person.
/// </summary>
/// <value>The person's last name.</value>
[Required]
[StringLength( 25 )]
public string LastName { get; set; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
namespace ApiVersioning.Examples.Models.V2;

using System.ComponentModel.DataAnnotations;

/// <summary>
/// Represents an order.
/// </summary>
public class Order
{
/// <summary>
/// Gets or sets the unique identifier for the order.
/// </summary>
/// <value>The order's unique identifier.</value>
public int Id { get; set; }

/// <summary>
/// Gets or sets the date and time when the order was created.
/// </summary>
/// <value>The order's creation date.</value>
public DateTimeOffset CreatedDate { get; set; } = DateTimeOffset.Now;

/// <summary>
/// Gets or sets the date and time when the order becomes effective.
/// </summary>
/// <value>The order's effective date.</value>
public DateTimeOffset EffectiveDate { get; set; } = DateTimeOffset.Now;

/// <summary>
/// Gets or sets the name of the ordering customer.
/// </summary>
/// <value>The name of the customer that placed the order.</value>
[Required]
public string Customer { get; set; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
namespace ApiVersioning.Examples.Models.V2;

using System.ComponentModel.DataAnnotations;

/// <summary>
/// Represents a person.
/// </summary>
public class Person
{
/// <summary>
/// Gets or sets the unique identifier for a person.
/// </summary>
/// <value>The person's unique identifier.</value>
public int Id { get; set; }

/// <summary>
/// Gets or sets the first name of a person.
/// </summary>
/// <value>The person's first name.</value>
[Required]
[StringLength( 25 )]
public string FirstName { get; set; }

/// <summary>
/// Gets or sets the last name of a person.
/// </summary>
/// <value>The person's last name.</value>
[Required]
[StringLength( 25 )]
public string LastName { get; set; }

/// <summary>
/// Gets or sets the email address for a person.
/// </summary>
/// <value>The person's email address.</value>
public string Email { get; set; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
namespace ApiVersioning.Examples.Models.V3;

using System.ComponentModel.DataAnnotations;

/// <summary>
/// Represents an order.
/// </summary>
public class Order
{
/// <summary>
/// Gets or sets the unique identifier for the order.
/// </summary>
/// <value>The order's unique identifier.</value>
public int Id { get; set; }

/// <summary>
/// Gets or sets the date and time when the order was created.
/// </summary>
/// <value>The order's creation date.</value>
public DateTimeOffset CreatedDate { get; set; } = DateTimeOffset.Now;

/// <summary>
/// Gets or sets the date and time when the order becomes effective.
/// </summary>
/// <value>The order's effective date.</value>
public DateTimeOffset EffectiveDate { get; set; } = DateTimeOffset.Now;

/// <summary>
/// Gets or sets the name of the ordering customer.
/// </summary>
/// <value>The name of the customer that placed the order.</value>
[Required]
public string Customer { get; set; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
namespace ApiVersioning.Examples.Models.V3;

using System.ComponentModel.DataAnnotations;

/// <summary>
/// Represents a person.
/// </summary>
public class Person
{
/// <summary>
/// Gets or sets the unique identifier for a person.
/// </summary>
/// <value>The person's unique identifier.</value>
public int Id { get; set; }

/// <summary>
/// Gets or sets the first name of a person.
/// </summary>
/// <value>The person's first name.</value>
[Required]
[StringLength( 25 )]
public string FirstName { get; set; }

/// <summary>
/// Gets or sets the last name of a person.
/// </summary>
/// <value>The person's last name.</value>
[Required]
[StringLength( 25 )]
public string LastName { get; set; }

/// <summary>
/// Gets or sets the email address for a person.
/// </summary>
/// <value>The person's email address.</value>
public string Email { get; set; }

/// <summary>
/// Gets or sets the telephone number for a person.
/// </summary>
/// <value>The person's telephone number.</value>
public string Phone { get; set; }
}

0 comments on commit 93bd8dc

Please sign in to comment.