mirror of
https://github.com/collinbarrett/FilterLists.git
synced 2026-03-11 09:04:27 +00:00
feat(dir): ✨ migrate OpenAPI & SwaggerUI
This commit is contained in:
parent
07343fa0d9
commit
e0647a1303
7 changed files with 254 additions and 30 deletions
|
|
@ -1,6 +1,9 @@
|
|||
using FilterLists.Directory.Application.Queries;
|
||||
using MediatR;
|
||||
using Microsoft.AspNetCore.Http.HttpResults;
|
||||
using Microsoft.OpenApi.Any;
|
||||
using Microsoft.OpenApi.Models;
|
||||
using static FilterLists.Directory.Api.OpenApi.OpenApiTags;
|
||||
using static FilterLists.Directory.Application.Queries.GetListDetails;
|
||||
|
||||
namespace FilterLists.Directory.Api;
|
||||
|
|
@ -10,47 +13,106 @@ internal static class Endpoints
|
|||
internal static void MapEndpoints(this WebApplication app)
|
||||
{
|
||||
app.MapGet("/languages",
|
||||
(IMediator mediator, CancellationToken ct) =>
|
||||
mediator.CreateStream(new GetLanguages.Request(), ct)
|
||||
);
|
||||
(IMediator mediator, CancellationToken ct) =>
|
||||
mediator.CreateStream(new GetLanguages.Request(), ct)
|
||||
)
|
||||
.WithOpenApi(operation => new OpenApiOperation(operation)
|
||||
{
|
||||
Tags = [LanguagesTag],
|
||||
Summary = "Gets the languages targeted by the FilterLists.",
|
||||
OperationId = nameof(GetLanguages)
|
||||
});
|
||||
|
||||
app.MapGet("/licenses",
|
||||
(IMediator mediator, CancellationToken ct) =>
|
||||
mediator.CreateStream(new GetLicenses.Request(), ct)
|
||||
);
|
||||
(IMediator mediator, CancellationToken ct) =>
|
||||
mediator.CreateStream(new GetLicenses.Request(), ct)
|
||||
)
|
||||
.WithOpenApi(operation => new OpenApiOperation(operation)
|
||||
{
|
||||
Tags = [LicensesTag],
|
||||
Summary = "Gets the licenses applied to the FilterLists.",
|
||||
OperationId = nameof(GetLicenses)
|
||||
});
|
||||
|
||||
app.MapGet("/lists",
|
||||
(IMediator mediator, CancellationToken ct) =>
|
||||
mediator.CreateStream(new GetLists.Request(), ct)
|
||||
);
|
||||
(IMediator mediator, CancellationToken ct) =>
|
||||
mediator.CreateStream(new GetLists.Request(), ct)
|
||||
)
|
||||
.WithOpenApi(operation => new OpenApiOperation(operation)
|
||||
{
|
||||
Tags = [FilterListsTag],
|
||||
Summary = "Gets the FilterLists.",
|
||||
OperationId = nameof(GetLists)
|
||||
});
|
||||
|
||||
app.MapGet("/lists/{id:int}", async Task<Results<Ok<ListDetailsVm>, NotFound>>
|
||||
(int id, IMediator mediator, CancellationToken ct) =>
|
||||
{
|
||||
var list = await mediator.Send(new Request(id), ct);
|
||||
return list is not null
|
||||
? TypedResults.Ok(list)
|
||||
: TypedResults.NotFound();
|
||||
});
|
||||
(int id, IMediator mediator, CancellationToken ct) =>
|
||||
{
|
||||
var list = await mediator.Send(new Request(id), ct);
|
||||
return list is not null
|
||||
? TypedResults.Ok(list)
|
||||
: TypedResults.NotFound();
|
||||
})
|
||||
.WithOpenApi(operation => new OpenApiOperation(operation)
|
||||
{
|
||||
Tags = [FilterListsTag],
|
||||
Summary = "Gets the details of the FilterList.",
|
||||
OperationId = nameof(GetListDetails),
|
||||
Parameters =
|
||||
[
|
||||
new OpenApiParameter
|
||||
{
|
||||
Name = "id",
|
||||
In = ParameterLocation.Path,
|
||||
Description = "The identifier of the FilterList.",
|
||||
Required = true,
|
||||
Example = new OpenApiInteger(1)
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
app.MapGet("/maintainers",
|
||||
(IMediator mediator, CancellationToken ct) =>
|
||||
mediator.CreateStream(new GetMaintainers.Request(), ct)
|
||||
);
|
||||
(IMediator mediator, CancellationToken ct) =>
|
||||
mediator.CreateStream(new GetMaintainers.Request(), ct)
|
||||
)
|
||||
.WithOpenApi(operation => new OpenApiOperation(operation)
|
||||
{
|
||||
Tags = [MaintainersTag],
|
||||
Summary = "Gets the maintainers of the FilterLists.",
|
||||
OperationId = nameof(GetMaintainers)
|
||||
});
|
||||
|
||||
app.MapGet("/software",
|
||||
(IMediator mediator, CancellationToken ct) =>
|
||||
mediator.CreateStream(new GetSoftware.Request(), ct)
|
||||
);
|
||||
(IMediator mediator, CancellationToken ct) =>
|
||||
mediator.CreateStream(new GetSoftware.Request(), ct)
|
||||
)
|
||||
.WithOpenApi(operation => new OpenApiOperation(operation)
|
||||
{
|
||||
Tags = [SoftwareTag],
|
||||
Summary = "Gets the software that subscribes to the FilterLists.",
|
||||
OperationId = nameof(GetSoftware)
|
||||
});
|
||||
|
||||
app.MapGet("/syntaxes",
|
||||
(IMediator mediator, CancellationToken ct) =>
|
||||
mediator.CreateStream(new GetSyntaxes.Request(), ct)
|
||||
);
|
||||
(IMediator mediator, CancellationToken ct) =>
|
||||
mediator.CreateStream(new GetSyntaxes.Request(), ct)
|
||||
)
|
||||
.WithOpenApi(operation => new OpenApiOperation(operation)
|
||||
{
|
||||
Tags = [SyntaxesTag],
|
||||
Summary = "Gets the syntaxes of the FilterLists.",
|
||||
OperationId = nameof(GetSyntaxes)
|
||||
});
|
||||
|
||||
app.MapGet("/tags",
|
||||
(IMediator mediator, CancellationToken ct) =>
|
||||
mediator.CreateStream(new GetTags.Request(), ct)
|
||||
);
|
||||
(IMediator mediator, CancellationToken ct) =>
|
||||
mediator.CreateStream(new GetTags.Request(), ct)
|
||||
)
|
||||
.WithOpenApi(operation => new OpenApiOperation(operation)
|
||||
{
|
||||
Tags = [TagsTag],
|
||||
Summary = "Gets the tags of the FilterLists.",
|
||||
OperationId = nameof(GetTags)
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -11,4 +11,9 @@
|
|||
<ProjectReference Include="..\FilterLists.Directory.Application\FilterLists.Directory.Application.csproj"/>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="8.0.6"/>
|
||||
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.6.2"/>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,38 @@
|
|||
using Microsoft.OpenApi.Models;
|
||||
using ConfigurationExtensions = FilterLists.Directory.Application.ConfigurationExtensions;
|
||||
|
||||
namespace FilterLists.Directory.Api.OpenApi;
|
||||
|
||||
internal static class OpenApiConfigurationExtensions
|
||||
{
|
||||
internal static void AddOpenApiGen(this IServiceCollection services)
|
||||
{
|
||||
services.AddEndpointsApiExplorer();
|
||||
services.AddSwaggerGen(options =>
|
||||
{
|
||||
options.SwaggerDoc(
|
||||
"v1",
|
||||
new OpenApiInfo
|
||||
{
|
||||
Title = "FilterLists Directory API",
|
||||
Description = "An ASP.NET Core API serving the core FilterList information.",
|
||||
Version = "v1",
|
||||
TermsOfService =
|
||||
new Uri("https://github.com/collinbarrett/FilterLists/blob/main/.github/CODE_OF_CONDUCT.md"),
|
||||
Contact = new OpenApiContact { Name = "FilterLists", Url = new Uri("https://filterlists.com") },
|
||||
License = new OpenApiLicense
|
||||
{
|
||||
Name = "MIT License",
|
||||
Url = new Uri("https://github.com/collinbarrett/FilterLists/blob/main/LICENSE")
|
||||
}
|
||||
});
|
||||
|
||||
// include view model xml comments
|
||||
var xmlFilename = $"{typeof(ConfigurationExtensions).Assembly.GetName().Name}.xml";
|
||||
options.IncludeXmlComments(Path.Combine(AppContext.BaseDirectory, xmlFilename));
|
||||
|
||||
// include OpenApiTag Description and ExternalDocs
|
||||
options.DocumentFilter<OpenApiTags.TagDescriptionsDocumentFilter>();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,106 @@
|
|||
using FilterLists.Directory.Infrastructure.Persistence.Queries.Context;
|
||||
using FilterLists.Directory.Infrastructure.Persistence.Queries.Entities;
|
||||
using JetBrains.Annotations;
|
||||
using Microsoft.OpenApi.Models;
|
||||
using Swashbuckle.AspNetCore.SwaggerGen;
|
||||
|
||||
namespace FilterLists.Directory.Api.OpenApi;
|
||||
|
||||
internal static class OpenApiTags
|
||||
{
|
||||
internal static readonly OpenApiTag LanguagesTag = new()
|
||||
{
|
||||
Name = nameof(QueryDbContext.Languages),
|
||||
Description = "A written form of communication used by sites targeted by a FilterList",
|
||||
ExternalDocs = new OpenApiExternalDocs
|
||||
{
|
||||
Description = $"{nameof(FilterLists)} {nameof(Language)} Wiki",
|
||||
Url = new Uri($"https://github.com/collinbarrett/FilterLists/wiki/{nameof(Language)}")
|
||||
}
|
||||
};
|
||||
|
||||
internal static readonly OpenApiTag LicensesTag = new()
|
||||
{
|
||||
Name = nameof(QueryDbContext.Licenses),
|
||||
Description = "A legal document governing the use or redistribution of a FilterList",
|
||||
ExternalDocs = new OpenApiExternalDocs
|
||||
{
|
||||
Description = $"{nameof(FilterLists)} {nameof(License)} Wiki",
|
||||
Url = new Uri($"https://github.com/collinbarrett/FilterLists/wiki/{nameof(License)}")
|
||||
}
|
||||
};
|
||||
|
||||
internal static readonly OpenApiTag FilterListsTag = new()
|
||||
{
|
||||
Name = nameof(QueryDbContext.FilterLists),
|
||||
Description = "A text file containing a list of rules for blocking or manipulating internet traffic",
|
||||
ExternalDocs = new OpenApiExternalDocs
|
||||
{
|
||||
Description = $"{nameof(FilterLists)} {nameof(FilterList)} Wiki",
|
||||
Url = new Uri($"https://github.com/collinbarrett/FilterLists/wiki/{nameof(FilterList)}")
|
||||
}
|
||||
};
|
||||
|
||||
internal static readonly OpenApiTag MaintainersTag = new()
|
||||
{
|
||||
Name = nameof(QueryDbContext.Maintainers),
|
||||
Description = "An individual, group, or organization who maintains one or more FilterLists",
|
||||
ExternalDocs = new OpenApiExternalDocs
|
||||
{
|
||||
Description = $"{nameof(FilterLists)} {nameof(Maintainer)} Wiki",
|
||||
Url = new Uri($"https://github.com/collinbarrett/FilterLists/wiki/{nameof(Maintainer)}")
|
||||
}
|
||||
};
|
||||
|
||||
internal static readonly OpenApiTag SoftwareTag = new()
|
||||
{
|
||||
Name = nameof(QueryDbContext.Software),
|
||||
Description = "An application, browser extension, or other utility that consumes FilterLists",
|
||||
ExternalDocs = new OpenApiExternalDocs
|
||||
{
|
||||
Description = $"{nameof(FilterLists)} {nameof(Software)} Wiki",
|
||||
Url = new Uri($"https://github.com/collinbarrett/FilterLists/wiki/{nameof(Software)}")
|
||||
}
|
||||
};
|
||||
|
||||
internal static readonly OpenApiTag SyntaxesTag = new()
|
||||
{
|
||||
Name = nameof(QueryDbContext.Syntaxes),
|
||||
Description = "A named set of rules that govern the format of a FilterList",
|
||||
ExternalDocs = new OpenApiExternalDocs
|
||||
{
|
||||
Description = $"{nameof(FilterLists)} {nameof(Syntax)} Wiki",
|
||||
Url = new Uri($"https://github.com/collinbarrett/FilterLists/wiki/{nameof(Syntax)}")
|
||||
}
|
||||
};
|
||||
|
||||
internal static readonly OpenApiTag TagsTag = new()
|
||||
{
|
||||
Name = nameof(QueryDbContext.Tags),
|
||||
Description =
|
||||
"A generic taxonomy applied to a FilterList to provide information about its contents and/or purpose",
|
||||
ExternalDocs = new OpenApiExternalDocs
|
||||
{
|
||||
Description = $"{nameof(FilterLists)} {nameof(Tag)} Wiki",
|
||||
Url = new Uri($"https://github.com/collinbarrett/FilterLists/wiki/{nameof(Tag)}")
|
||||
}
|
||||
};
|
||||
|
||||
[UsedImplicitly]
|
||||
internal class TagDescriptionsDocumentFilter : IDocumentFilter
|
||||
{
|
||||
public void Apply(OpenApiDocument swaggerDoc, DocumentFilterContext context)
|
||||
{
|
||||
swaggerDoc.Tags =
|
||||
[
|
||||
LanguagesTag,
|
||||
LicensesTag,
|
||||
FilterListsTag,
|
||||
MaintainersTag,
|
||||
SoftwareTag,
|
||||
SyntaxesTag,
|
||||
TagsTag
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,4 +1,5 @@
|
|||
using FilterLists.Directory.Api;
|
||||
using FilterLists.Directory.Api.OpenApi;
|
||||
using FilterLists.Directory.Application;
|
||||
|
||||
var builder = WebApplication.CreateBuilder(args);
|
||||
|
|
@ -6,6 +7,7 @@
|
|||
builder.WebHost.ConfigureKestrel(serverOptions => serverOptions.AddServerHeader = false);
|
||||
builder.AddServiceDefaults();
|
||||
builder.Services.AddProblemDetails();
|
||||
builder.Services.AddOpenApiGen();
|
||||
builder.AddApplication();
|
||||
|
||||
var app = builder.Build();
|
||||
|
|
@ -13,5 +15,7 @@
|
|||
app.UseExceptionHandler();
|
||||
app.MapEndpoints();
|
||||
app.MapDefaultEndpoints();
|
||||
app.UseSwagger();
|
||||
app.UseSwaggerUI();
|
||||
|
||||
app.Run();
|
||||
|
|
@ -5,7 +5,7 @@
|
|||
"commandName": "Project",
|
||||
"dotnetRunMessages": true,
|
||||
"launchBrowser": true,
|
||||
"launchUrl": "lists",
|
||||
"launchUrl": "swagger/index.html",
|
||||
"applicationUrl": "http://localhost:5444",
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
|
|
@ -15,7 +15,7 @@
|
|||
"commandName": "Project",
|
||||
"dotnetRunMessages": true,
|
||||
"launchBrowser": true,
|
||||
"launchUrl": "lists",
|
||||
"launchUrl": "swagger/index.html",
|
||||
"applicationUrl": "https://localhost:7490;http://localhost:5444",
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
|
|
|
|||
|
|
@ -4,6 +4,15 @@
|
|||
<TargetFramework>net8.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
|
||||
<NoWarn>1591;1701;1702</NoWarn>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
|
||||
<NoWarn>1591;1701;1702</NoWarn>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
|
|||
Loading…
Reference in a new issue