V13-FE-011: finalize search list layout slice
This commit is contained in:
+78
@@ -0,0 +1,78 @@
|
||||
using System.Text.RegularExpressions;
|
||||
using Microsoft.OpenApi.Any;
|
||||
using Microsoft.OpenApi.Models;
|
||||
using Shared.Contracts.Generated;
|
||||
using Shared.Problems;
|
||||
using Swashbuckle.AspNetCore.SwaggerGen;
|
||||
|
||||
namespace Shared.Contracts;
|
||||
|
||||
public static class KbxApiContractSwaggerExtensions
|
||||
{
|
||||
public static void AddKbxApiContracts(this SwaggerGenOptions options)
|
||||
{
|
||||
options.OperationFilter<KbxApiContractOperationFilter>();
|
||||
options.OperationFilter<KbxProblemOpenApiOperationFilter>();
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class KbxApiContractOperationFilter : IOperationFilter
|
||||
{
|
||||
public void Apply(OpenApiOperation operation, OperationFilterContext context)
|
||||
{
|
||||
var method = context.ApiDescription.HttpMethod?.ToUpperInvariant();
|
||||
var relative = "/" + (context.ApiDescription.RelativePath ?? string.Empty).TrimStart('/');
|
||||
var normalized = Normalize(relative);
|
||||
var contract = KbxApiCatalog.All.FirstOrDefault(x =>
|
||||
x.Method == method && Normalize(x.Path) == normalized);
|
||||
if (contract is null) return;
|
||||
|
||||
operation.OperationId = contract.Id;
|
||||
operation.Extensions["x-kbx-permission"] = new OpenApiString(contract.Permission ?? string.Empty);
|
||||
operation.Extensions["x-kbx-idempotency"] = new OpenApiString(contract.Idempotency);
|
||||
operation.Extensions["x-kbx-kind"] = new OpenApiString(contract.Kind);
|
||||
}
|
||||
|
||||
private static string Normalize(string value) =>
|
||||
Regex.Replace(value, @"\{([^}:]+):[^}]+\}", "{$1}").ToLowerInvariant();
|
||||
}
|
||||
|
||||
public sealed class KbxProblemOpenApiOperationFilter : IOperationFilter
|
||||
{
|
||||
public void Apply(OpenApiOperation operation, OperationFilterContext context)
|
||||
{
|
||||
var problem = new OpenApiSchema
|
||||
{
|
||||
OneOf = new List<OpenApiSchema>
|
||||
{
|
||||
context.SchemaGenerator.GenerateSchema(typeof(KbxValidationProblem), context.SchemaRepository),
|
||||
context.SchemaGenerator.GenerateSchema(typeof(KbxBusinessProblem), context.SchemaRepository),
|
||||
context.SchemaGenerator.GenerateSchema(typeof(KbxConflictProblem), context.SchemaRepository),
|
||||
context.SchemaGenerator.GenerateSchema(typeof(KbxPermissionProblem), context.SchemaRepository),
|
||||
context.SchemaGenerator.GenerateSchema(typeof(KbxNotFoundProblem), context.SchemaRepository),
|
||||
context.SchemaGenerator.GenerateSchema(typeof(KbxIntegrationProblem), context.SchemaRepository),
|
||||
context.SchemaGenerator.GenerateSchema(typeof(KbxSystemProblem), context.SchemaRepository),
|
||||
}
|
||||
};
|
||||
|
||||
Add(operation, "400", "Validation problem", problem);
|
||||
Add(operation, "403", "Permission problem", problem);
|
||||
Add(operation, "404", "Not found problem", problem);
|
||||
Add(operation, "409", "Conflict or business rule problem", problem);
|
||||
Add(operation, "422", "Business rule problem", problem);
|
||||
Add(operation, "500", "System problem", problem);
|
||||
}
|
||||
|
||||
private static void Add(OpenApiOperation operation, string status, string description, OpenApiSchema schema)
|
||||
{
|
||||
if (operation.Responses.ContainsKey(status)) return;
|
||||
operation.Responses[status] = new OpenApiResponse
|
||||
{
|
||||
Description = description,
|
||||
Content = new Dictionary<string, OpenApiMediaType>
|
||||
{
|
||||
["application/json"] = new() { Schema = schema }
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user