79 lines
3.4 KiB
C#
79 lines
3.4 KiB
C#
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 }
|
|
}
|
|
};
|
|
}
|
|
}
|