-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Add initial SwaggerUi support (#5)
- Loading branch information
Showing
32 changed files
with
743 additions
and
20 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
1 change: 1 addition & 0 deletions
1
demo/APIWeaver.MinimalApi.Demo/APIWeaver.MinimalApi.Demo.csproj
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,14 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
<ItemGroup> | ||
<ProjectReference Include="..\APIWeaver\APIWeaver.csproj" /> | ||
</ItemGroup> | ||
|
||
<ItemGroup> | ||
<ProjectReference Include="..\APIWeaver\APIWeaver.csproj"/> | ||
</ItemGroup> | ||
|
||
<ItemGroup> | ||
|
||
<EmbeddedResource Include="**/swagger-ui-dist/swagger-ui-bundle.js;**/swagger-ui-dist/swagger-ui-standalone-preset.js;**/swagger-ui-dist/*.css;**/swagger-ui-dist/*.html;**/swagger-ui-dist/*.png;swagger-initializer.js"> | ||
<LogicalName>SwaggerUiAssets.%(Filename)%(Extension)</LogicalName> | ||
</EmbeddedResource> | ||
</ItemGroup> | ||
|
||
</Project> |
49 changes: 49 additions & 0 deletions
49
src/APIWeaver.Swagger/Extensions/ApplicationBuilderExtensions.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
using APIWeaver.Swagger.Middleware; | ||
using Microsoft.AspNetCore.Builder; | ||
using Microsoft.Extensions.DependencyInjection; | ||
using Microsoft.Extensions.FileProviders; | ||
using Microsoft.Extensions.Options; | ||
|
||
namespace APIWeaver.Swagger.Extensions; | ||
|
||
/// <summary> | ||
/// Extension methods for <see cref="IApplicationBuilder" />. | ||
/// </summary> | ||
public static class ApplicationBuilderExtensions | ||
{ | ||
/// <summary> | ||
/// Configures the application to use Swagger UI. | ||
/// </summary> | ||
/// <param name="appBuilder"><see cref="IApplicationBuilder" />.</param> | ||
/// <param name="options">An action to configure the Swagger UI options.</param> | ||
public static IApplicationBuilder UseSwaggerUi(this IApplicationBuilder appBuilder, Action<SwaggerUiConfiguration>? options = null) | ||
{ | ||
var configuredOptions = appBuilder.ApplicationServices.GetRequiredService<IOptions<SwaggerUiConfiguration>>().Value; | ||
options?.Invoke(configuredOptions); | ||
var requestPath = $"/{configuredOptions.RoutePrefix.TrimEnd('/')}"; | ||
|
||
appBuilder.MapWhen(context => context.Request.Path.StartsWithSegments(requestPath), builder => | ||
{ | ||
builder.UseMiddleware<SwaggerConfigurationMiddleware>(); | ||
|
||
builder.UseStaticFiles(new StaticFileOptions | ||
{ | ||
RequestPath = requestPath, | ||
FileProvider = new EmbeddedFileProvider(typeof(SwaggerConfigurationMiddleware).Assembly, "SwaggerUiAssets") | ||
}); | ||
|
||
builder.Use((context, next) => | ||
{ | ||
if (!context.Response.HasStarted) | ||
{ | ||
context.Response.Redirect($"{requestPath}/index.html"); | ||
return Task.CompletedTask; | ||
} | ||
|
||
return next(); | ||
}); | ||
}); | ||
|
||
return appBuilder; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
using Microsoft.AspNetCore.Http; | ||
|
||
namespace APIWeaver.Swagger.Extensions; | ||
|
||
internal static class PathStringExtensions | ||
{ | ||
public static bool EndsWith(this PathString path, string segment) => path.HasValue && path.Value.EndsWith(segment, StringComparison.OrdinalIgnoreCase); | ||
} |
19 changes: 19 additions & 0 deletions
19
src/APIWeaver.Swagger/Extensions/SwaggerOptionsExtensions.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
namespace APIWeaver.Swagger.Extensions; | ||
|
||
/// <summary> | ||
/// Extension methods for <see cref="SwaggerOptions" />. | ||
/// </summary> | ||
public static class SwaggerOptionsExtensions | ||
{ | ||
/// <summary> | ||
/// Configures the OpenAPI endpoint for the Swagger UI. | ||
/// </summary> | ||
/// <param name="options"><see cref="SwaggerOptions" />.</param> | ||
/// <param name="name">The name of the OpenAPI document.</param> | ||
/// <param name="url">The URL where the OpenAPI document can be found.</param> | ||
public static SwaggerOptions WithOpenApiEndpoint(this SwaggerOptions options, string name, string url) | ||
{ | ||
options.Urls.Add(new Url(name, url)); | ||
return options; | ||
} | ||
} |
30 changes: 30 additions & 0 deletions
30
src/APIWeaver.Swagger/Extensions/SwaggerUiConfigurationExtensions.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
namespace APIWeaver.Swagger.Extensions; | ||
|
||
/// <summary> | ||
/// Extension methods for <see cref="SwaggerUiConfiguration" />. | ||
/// </summary> | ||
public static class SwaggerUiConfigurationExtensions | ||
{ | ||
/// <summary> | ||
/// Configures OAuth2 options for the Swagger UI. | ||
/// </summary> | ||
/// <param name="swaggerUiConfiguration"><see cref="SwaggerUiConfiguration" />.</param> | ||
/// <param name="authOptions">An action to configure the OAuth2 options.</param> | ||
public static SwaggerUiConfiguration WithOAuth2Options(this SwaggerUiConfiguration swaggerUiConfiguration, Action<OAuth2Options> authOptions) | ||
{ | ||
swaggerUiConfiguration.OAuth2Options ??= new OAuth2Options(); | ||
authOptions.Invoke(swaggerUiConfiguration.OAuth2Options); | ||
return swaggerUiConfiguration; | ||
} | ||
|
||
/// <summary> | ||
/// Configures Swagger options for the Swagger UI. | ||
/// </summary> | ||
/// <param name="swaggerUiConfiguration"><see cref="SwaggerUiConfiguration" />.</param> | ||
/// <param name="swaggerOptions">An action to configure the Swagger options.</param> | ||
public static SwaggerUiConfiguration WithSwaggerOptions(this SwaggerUiConfiguration swaggerUiConfiguration, Action<SwaggerOptions> swaggerOptions) | ||
{ | ||
swaggerOptions.Invoke(swaggerUiConfiguration.SwaggerOptions); | ||
return swaggerUiConfiguration; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
using System.Text.Json; | ||
|
||
namespace APIWeaver.Swagger.Helper; | ||
|
||
internal static class JsonSerializerHelper | ||
{ | ||
public static readonly JsonSerializerOptions SerializerOptions = new() | ||
{ | ||
PropertyNamingPolicy = JsonNamingPolicy.CamelCase, | ||
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull | ||
}; | ||
} |
37 changes: 37 additions & 0 deletions
37
src/APIWeaver.Swagger/Middleware/SwaggerConfigurationMiddleware.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
using System.Net.Mime; | ||
using APIWeaver.Swagger.Helper; | ||
using Microsoft.AspNetCore.Hosting; | ||
using Microsoft.AspNetCore.Http; | ||
using Microsoft.Extensions.DependencyInjection; | ||
using Microsoft.Extensions.Options; | ||
|
||
namespace APIWeaver.Swagger.Middleware; | ||
|
||
internal sealed class SwaggerConfigurationMiddleware(RequestDelegate next) | ||
{ | ||
|
||
public async Task InvokeAsync(HttpContext context) | ||
{ | ||
if (context.Request.Method == HttpMethods.Get && context.Request.Path.EndsWith("configuration.json")) | ||
{ | ||
await HandleRequestAsync(context, context.RequestAborted); | ||
return; | ||
} | ||
|
||
await next(context); | ||
} | ||
|
||
private static async Task HandleRequestAsync(HttpContext context, CancellationToken cancellationToken) | ||
{ | ||
var configuration = context.RequestServices.GetRequiredService<IOptions<SwaggerUiConfiguration>>().Value; | ||
if (configuration.SwaggerOptions.Urls.Count == 0) | ||
{ | ||
var applicationName = context.RequestServices.GetRequiredService<IWebHostEnvironment>().ApplicationName; | ||
configuration.SwaggerOptions.WithOpenApiEndpoint(applicationName, "https://petstore.swagger.io/v2/swagger.json"); | ||
} | ||
|
||
var response = context.Response; | ||
response.Headers.ContentType = MediaTypeNames.Application.Json; | ||
await response.WriteAsJsonAsync(configuration, JsonSerializerHelper.SerializerOptions, cancellationToken); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
namespace APIWeaver.Swagger.Models; | ||
|
||
/// <summary> | ||
/// OAuth configuration for Swagger UI. | ||
/// </summary> | ||
public sealed class OAuth2Options | ||
{ | ||
/// <summary> | ||
/// The client ID for your application. You must first create an application at the service provider and obtain this value. | ||
/// </summary> | ||
public string ClientId { get; set; } = null!; | ||
|
||
/// <summary> | ||
/// The client secret for your application. You must first create an application at the service provider and obtain this value. | ||
/// </summary> | ||
public string ClientSecret { get; set; } = null!; | ||
|
||
/// <summary> | ||
/// The realm of the client application. | ||
/// </summary> | ||
public string Realm { get; set; } = null!; | ||
|
||
/// <summary> | ||
/// The application name. | ||
/// </summary> | ||
public string? AppName { get; set; } | ||
|
||
/// <summary> | ||
/// The scope separator. The standard is a space (" "), but some services use a comma (","). | ||
/// </summary> | ||
public string ScopeSeparator { get; set; } = " "; | ||
|
||
/// <summary> | ||
/// String array of initially selected oauth scopes. | ||
/// </summary> | ||
public IEnumerable<string> Scopes { get; set; } = []; | ||
|
||
/// <summary> | ||
/// Additional query parameters added to authorizationUrl and tokenUrl. | ||
/// </summary> | ||
public Dictionary<string, string> AdditionalQueryStringParams { get; set; } = new(); | ||
|
||
/// <summary> | ||
/// If true, the "Authorize" button will be hidden for operations that do not have any OAuth2 scopes. | ||
/// </summary> | ||
public bool UseBasicAuthenticationWithAccessCodeGrant { get; set; } | ||
} |
Oops, something went wrong.