Skip to content
This repository has been archived by the owner on Sep 2, 2022. It is now read-only.

Commit

Permalink
Merge remote-tracking branch 'origin/bug/VP-3148' into odt/dev
Browse files Browse the repository at this point in the history
  • Loading branch information
asvishnyakov committed Aug 13, 2020
2 parents b95390b + ff7c458 commit b368a3e
Show file tree
Hide file tree
Showing 12 changed files with 144 additions and 59 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
namespace VirtoCommerce.Storefront.Infrastructure.Swagger
{
public class ApiSchemaOptions
{
public bool NameAndOrderRequestBody { get; set; }

public OpenApiSpecificationVersion OpenApiSpecificationVersion { get; set; }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
namespace VirtoCommerce.Storefront.Infrastructure.Swagger
{
public enum ApiSchemaVersion
{
V1,
V2
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
using Microsoft.Extensions.Options;
using Microsoft.OpenApi.Any;
using Microsoft.OpenApi.Models;
using Swashbuckle.AspNetCore.SwaggerGen;

namespace VirtoCommerce.Storefront.Infrastructure.Swagger
{
public class NameAndOrderRequestBodyFilter: IRequestBodyFilter
{
private readonly SwaggerOptions _swaggerOptions;

public NameAndOrderRequestBodyFilter(IOptions<SwaggerOptions> swaggerOptions)
{
_swaggerOptions = swaggerOptions.Value;
}

public void Apply(OpenApiRequestBody requestBody, RequestBodyFilterContext context)
{
// Even if it's v2 or request body shouldn't be named
// we want name it because of bugs and different approaches in generation tools
var bodyName = _swaggerOptions.Schema.NameAndOrderRequestBody
? context.BodyParameterDescription.Name
: "body";
requestBody.Extensions.Add("x-name", new OpenApiString(bodyName));
requestBody.Extensions.Add("x-codegen-request-body-name", new OpenApiString(bodyName));
requestBody.Extensions.Add("x-ms-requestBody-name", new OpenApiString(bodyName));

if (_swaggerOptions.Schema.NameAndOrderRequestBody)
{
var bodyPosition = context.BodyParameterDescription.ParameterInfo().Position;
requestBody.Extensions.Add("x-position", new OpenApiInteger(bodyPosition));
requestBody.Extensions.Add("x-ms-requestBody-index", new OpenApiInteger(bodyPosition));
}
}
}
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
namespace VirtoCommerce.Storefront.Infrastructure.Swagger
{
public enum OpenApiSpecificationVersion
{
V2,
V3
}
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
using Microsoft.Extensions.Options;
using Microsoft.OpenApi.Any;
using Microsoft.OpenApi.Models;
using Swashbuckle.AspNetCore.SwaggerGen;

namespace VirtoCommerce.Storefront.Infrastructure.Swagger
{
public class ParameterOrderFilter: IParameterFilter
{
private readonly SwaggerOptions _swaggerOptions;

public ParameterOrderFilter(IOptions<SwaggerOptions> swaggerOptions)
{
_swaggerOptions = swaggerOptions.Value;
}

public void Apply(OpenApiParameter parameter, ParameterFilterContext context)
{
if (_swaggerOptions.Schema.NameAndOrderRequestBody)
{
// Explicitly specify parameters position
// Position for store and language is unknown and they should be last, so use int.MaxValue relative values
if (context.ParameterInfo != null)
{
parameter.Extensions.Add("x-position", new OpenApiInteger(context.ParameterInfo.Position));
}
else
{
switch (parameter.Name)
{
case "store":
parameter.Extensions.Add("x-position", new OpenApiInteger(int.MaxValue - 1));
break;
case "language":
parameter.Extensions.Add("x-position", new OpenApiInteger(int.MaxValue));
break;
}
}
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
using Microsoft.OpenApi.Models;
using Swashbuckle.AspNetCore.SwaggerGen;

namespace VirtoCommerce.Storefront.Infrastructure.Swagger
{
public class RequireRequestBodyFilter: IRequestBodyFilter
{
public void Apply(OpenApiRequestBody requestBody, RequestBodyFilterContext context)
{
requestBody.Required = true;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace VirtoCommerce.Storefront.Infrastructure.Swagger
{
public class SwaggerOptions
{
public ApiSchemaOptions Schema { get; set; }
}
}
18 changes: 14 additions & 4 deletions VirtoCommerce.Storefront/Startup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -339,28 +339,33 @@ public void ConfigureServices(IServiceCollection services)
options.MaxAge = TimeSpan.FromDays(30);
});

services.Configure<SwaggerOptions>(Configuration.GetSection("Swagger").Bind);

// Register the Swagger generator, defining 1 or more Swagger documents
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new OpenApiInfo { Title = "Storefront REST API documentation", Version = "v1" });
c.IgnoreObsoleteProperties();
c.IgnoreObsoleteActions();
c.ParameterFilter<ParameterOrderFilter>();
c.RequestBodyFilter<NameAndOrderRequestBodyFilter>();
c.RequestBodyFilter<RequireRequestBodyFilter>();
// To include 401 response type to actions that requires Authorization
c.OperationFilter<AuthResponsesOperationFilter>();
c.OperationFilter<ConsumeFromBodyFilter>();
c.OperationFilter<FileResponseTypeFilter>();
c.OperationFilter<OptionalParametersFilter>();
c.OperationFilter<ArrayInQueryParametersFilter>();
c.OperationFilter<FileResponseTypeFilter>();
c.OperationFilter<FileUploadOperationFilter>();
c.SchemaFilter<EnumSchemaFilter>();
c.SchemaFilter<NewtonsoftJsonIgnoreFilter>();
c.SchemaGeneratorOptions.UseAllOfToExtendReferenceSchemas = true;
// Use method name as operation ID, i.e. ApiAccount.GetOrganization instead of /storefrontapi/account/organization (will be treated as just organization method)
c.CustomOperationIds(apiDesc => apiDesc.TryGetMethodInfo(out var methodInfo) ? methodInfo.Name : null);
// To avoid errors with repeating type names
c.CustomSchemaIds(type => (Attribute.GetCustomAttribute(type, typeof(SwaggerSchemaIdAttribute)) as SwaggerSchemaIdAttribute)?.Id ?? type.FriendlyId());
});
services.AddSwaggerGenNewtonsoftSupport();

services.AddResponseCompression();

Expand Down Expand Up @@ -414,7 +419,12 @@ public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
});

// Enable middleware to serve generated Swagger as a JSON endpoint.
app.UseSwagger(c => c.RouteTemplate = "docs/{documentName}/docs.json");
app.UseSwagger(c =>
{
var options = app.ApplicationServices.GetService<IOptions<SwaggerOptions>>().Value;
c.SerializeAsV2 = options.Schema.OpenApiSpecificationVersion == OpenApiSpecificationVersion.V2;
c.RouteTemplate = "docs/{documentName}/docs.json";
});

var rewriteOptions = new RewriteOptions();
// Load IIS url rewrite rules from external file
Expand Down
1 change: 1 addition & 0 deletions VirtoCommerce.Storefront/VirtoCommerce.Storefront.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@
<PackageReference Include="Polly" Version="7.2.0" />
<PackageReference Include="Scrutor" Version="3.2.1" />
<PackageReference Include="StackExchange.Redis" Version="2.1.30" />
<PackageReference Include="Swashbuckle.AspNetCore.Newtonsoft" Version="5.3.3" />
<PackageReference Include="Swashbuckle.AspNetCore.Swagger" Version="5.3.3" />
<PackageReference Include="Swashbuckle.AspNetCore.SwaggerGen" Version="5.3.3" />
<PackageReference Include="Swashbuckle.AspNetCore.SwaggerUI" Version="5.3.3" />
Expand Down
6 changes: 6 additions & 0 deletions VirtoCommerce.Storefront/appsettings.json
Original file line number Diff line number Diff line change
Expand Up @@ -91,5 +91,11 @@
"SnapshotInLowPriorityThread": true,
"ProvideAnonymousTelemetry": true,
"FailedRequestLimit": 3
},
"Swagger": {
"Schema": {
"NameAndOrderRequestBody": true,
"OpenApiSpecificationVersion": "v3"
}
}
}

0 comments on commit b368a3e

Please sign in to comment.