Skip to content
Merged
Show file tree
Hide file tree
Changes from 71 commits
Commits
Show all changes
118 commits
Select commit Hold shift + click to select a range
6e2413b
Uninstall `Swashbuckle.AspNetCore` and install `Microsoft.AspNetCore.…
lauraneto Nov 3, 2025
5b035ff
Registered UI and removed or commented out Swashbuckle specific code
lauraneto Nov 3, 2025
ad9393c
Started configuring the different Open API documents
lauraneto Nov 3, 2025
fbd358d
Started moving configuration
lauraneto Nov 4, 2025
9449564
Simplifying configuration
lauraneto Nov 4, 2025
f04cd94
Added missing configuration for the Delivery API
lauraneto Nov 5, 2025
8a32af3
Added missing configurations for Management API
lauraneto Nov 5, 2025
e954aeb
Adjust Umbraco Extension template with OpenApi changes
lauraneto Nov 5, 2025
4dee734
Handle sub types in open api document generation
lauraneto Nov 6, 2025
a29faae
Renaming mime types transformer to align with others
lauraneto Nov 6, 2025
e6caf6e
Added discriminator configuration
lauraneto Nov 6, 2025
902bbad
Reference Umbraco.Cms.DevelopmentMode.Backoffice from integration tes…
lauraneto Nov 6, 2025
7011f39
Now configuring and using the HTTP json options instead of having cus…
lauraneto Nov 10, 2025
1c70f54
Merge branch 'main' into v18/feature/microsoft-open-api-document-gene…
lauraneto Nov 12, 2025
6574d58
Fixes to examples
lauraneto Nov 13, 2025
d9f82e9
Merge branch 'main' into v18/feature/microsoft-open-api-document-gene…
lauraneto Nov 13, 2025
d32628b
Update OpenAPI packages
lauraneto Nov 13, 2025
271f698
Mark most transformers as internal
lauraneto Nov 17, 2025
90e2422
Simplify adding backoffice security requirements to your API
lauraneto Nov 17, 2025
fa34354
Fix missing required properties
lauraneto Nov 17, 2025
6fed966
Re-order transformers to fix missing notification headers
lauraneto Nov 17, 2025
fc36c5f
Fix most build errors after regenerating client
lauraneto Nov 17, 2025
f9f358a
Merge branch 'main' into v18/feature/microsoft-open-api-document-gene…
lauraneto Nov 18, 2025
5ca3965
Fix mime types transformer being applied to Management API
lauraneto Nov 18, 2025
1c4f78d
Additional fixes
lauraneto Nov 18, 2025
4d3ab86
Additional fixes to file response types
lauraneto Nov 18, 2025
6583106
Configure Swagger UI documents
lauraneto Nov 18, 2025
62ee663
Clear server list
lauraneto Nov 18, 2025
91df6e2
Sort APIs in UI
lauraneto Nov 18, 2025
28a2df9
Merge branch 'main' into v18/feature/microsoft-open-api-document-gene…
lauraneto Dec 2, 2025
09a0c9e
Merge branch 'main' into v18/feature/microsoft-open-api-document-gene…
lauraneto Dec 2, 2025
aa717d0
Re-introduce schema handlers and fix issue with nullable enum schema …
lauraneto Dec 2, 2025
ed65b95
Simplify examples
lauraneto Dec 3, 2025
a95b6fd
Small optimization
lauraneto Dec 3, 2025
ba003c0
Merge branch 'main' into v18/feature/microsoft-open-api-document-gene…
lauraneto Dec 3, 2025
5d3abf7
Simplify nullability check in RequireNonNullablePropertiesSchemaTrans…
lauraneto Dec 4, 2025
7a2cd36
Merge branch 'v18/dev' into v18/feature/microsoft-open-api-document-g…
lauraneto Dec 4, 2025
1e85671
Remove unused property
lauraneto Dec 4, 2025
31c6808
Small fixes suggested by Claude
lauraneto Dec 4, 2025
c8c1d6f
Undo unintended space changes
lauraneto Dec 4, 2025
3ad75dd
Add unit tests for OpenAPI transformers
lauraneto Dec 4, 2025
9834cb0
Add unit tests for additional OpenAPI transformers
lauraneto Dec 4, 2025
ea31004
Rename SwaggerGen classes to OpenApi for consistency
lauraneto Dec 4, 2025
ed217ba
Update OpenAPI contract test for Microsoft.AspNetCore.OpenApi
lauraneto Dec 4, 2025
bf7d054
Disable Models Builder in integration tests by default
lauraneto Dec 7, 2025
2da7a6d
Rename Swagger references to OpenApi for consistency
lauraneto Dec 8, 2025
70de857
Merge branch 'v18/dev' into v18/feature/microsoft-open-api-document-g…
lauraneto Dec 11, 2025
cdb6c67
Re-generate Management API open api doc and UI client after merge
lauraneto Dec 11, 2025
4849df7
Add reference in comment to additional PR to fix file return types sc…
lauraneto Dec 11, 2025
0d54cfa
Fix Open API validation errors
lauraneto Dec 11, 2025
82a7dbb
Merge branch 'v18/dev' into v18/feature/microsoft-open-api-document-g…
lauraneto Dec 16, 2025
32265b4
OpenAPI: Replace ISchemaIdHandler/ISchemaIdSelector with static Umbra…
lauraneto Dec 19, 2025
b215c2a
Rename CustomOperationIdsTransformer to UmbracoOperationIdTransformer…
lauraneto Dec 19, 2025
e3e69f4
OpenAPI: Update Delivery API contract test for new document format
lauraneto Jan 6, 2026
4e911a7
Merge branch 'v18/dev' into v18/feature/microsoft-open-api-document-g…
lauraneto Jan 6, 2026
4172e9a
OpenAPI: Remove obsolete DocumentInclusionSelector abstraction
lauraneto Jan 6, 2026
8d27913
OpenAPI: Reorganize Management API OpenApi folder structure
lauraneto Jan 6, 2026
b5231d0
OpenAPI: Add ExcludeFromDefaultOpenApiDocument attribute
lauraneto Jan 6, 2026
2983f13
OpenAPI: Add UmbracoOpenApiOptions for configuring OpenAPI routes
lauraneto Jan 7, 2026
f874a80
Pipeline filters: Add OnPreMapEndpoints and rename OnEndpoints to OnP…
lauraneto Dec 17, 2025
685f680
OpenAPI: Move MapOpenApi to PreMapEndpoints hook
lauraneto Jan 7, 2026
09fa158
OpenAPI: Rename URL paths from swagger to openapi
lauraneto Jan 7, 2026
b0f4900
Merge branch 'v18/dev' into v18/feature/microsoft-open-api-document-g…
lauraneto Jan 15, 2026
30326bf
OpenAPI: Update Microsoft.AspNetCore.OpenApi to 10.0.2
lauraneto Jan 15, 2026
f9b3ac0
OpenAPI: Add AddOpenApiDocumentToUi extension method
lauraneto Jan 15, 2026
2754cea
OpenAPI: Make OpenApiRouteTemplatePipelineFilter internal
lauraneto Jan 15, 2026
65f914d
OpenAPI: Rename DeliveryApiSecurityFilter to DeliveryApiSecurityTrans…
lauraneto Jan 15, 2026
42483ce
OpenAPI: Simplify Delivery API member authentication configuration
lauraneto Jan 15, 2026
5ea01b0
OpenAPI: Add reference to proposal for custom JSON options support
lauraneto Jan 15, 2026
008ebaf
Move Delivery API transformers to OpenApi/Transformers folder
lauraneto Jan 15, 2026
aaea040
Update OpenAPI contract tests to use new URL format
lauraneto Jan 16, 2026
dc27bef
Merge branch 'v18/dev' into v18/feature/microsoft-open-api-document-g…
lauraneto Feb 4, 2026
49a2eba
Apply suggestions from code review
lauraneto Feb 5, 2026
b23c69f
Update src/Umbraco.Cms.Api.Delivery/DependencyInjection/UmbracoBuilde…
lauraneto Feb 5, 2026
f97ad76
Fix IAuthorizationService injection detection in BackOfficeSecurityRe…
lauraneto Feb 5, 2026
146f8cd
Remove unnecessary InterceptorsNamespaces from API projects
lauraneto Feb 5, 2026
a6ab23f
Remove default implementations from IUmbracoPipelineFilter methods
lauraneto Feb 5, 2026
a85a426
Update documentation for Microsoft.AspNetCore.OpenApi migration
lauraneto Feb 5, 2026
67ef8db
Update Swashbuckle.AspNetCore.SwaggerUI to 10.1.2
lauraneto Feb 5, 2026
0c1b1e2
Refactor OpenAPI contract tests with validation
lauraneto Feb 6, 2026
5492ae0
Merge branch 'v18/dev' into v18/feature/microsoft-open-api-document-g…
lauraneto Feb 25, 2026
9f780e5
Update ElementReferenceResponseModel type reference after OpenAPI reg…
lauraneto Feb 25, 2026
9f3feac
Add discriminator values to Delivery API polymorphic JSON serialization
lauraneto Feb 25, 2026
a207d81
Move Delivery API OpenAPI contract tests to Umbraco.Api.Delivery folder
lauraneto Feb 25, 2026
9348449
Update Microsoft.AspNetCore.OpenApi to 10.0.3 and Swashbuckle.AspNetC…
lauraneto Feb 25, 2026
950fbbf
Use JsonDerivedType attributes for Delivery API polymorphic serializa…
lauraneto Feb 25, 2026
94e665b
Add OpenAPI test for custom derived type extensibility
lauraneto Feb 25, 2026
898d1bf
Fix OpenAPI contract test failing on CI due to ContinuousIntegrationB…
lauraneto Mar 3, 2026
0f0adce
Merge remote-tracking branch 'origin/v18/dev' into v18/feature/micros…
lauraneto Mar 3, 2026
4036c97
Merge remote-tracking branch 'origin/v18/dev' into v18/feature/micros…
lauraneto Apr 13, 2026
fbc8d19
Merge branch 'v18/dev' into v18/feature/microsoft-open-api-document-g…
lauraneto Apr 14, 2026
b068e75
Bump Swashbuckle.AspNetCore.SwaggerUI to 10.1.7
lauraneto Apr 14, 2026
a8f09f5
Remove duplicate InternalsVisibleTo for Umbraco.Tests.UnitTests
lauraneto Apr 15, 2026
74858e2
Extract ReplaceOpenApiSchemaService into shared Api.Common helper
lauraneto Apr 16, 2026
59087d2
Merge remote-tracking branch 'origin/v18/dev' into v18/feature/micros…
lauraneto Apr 20, 2026
17c4c38
Tighten visibility and improve DI extension structure
lauraneto Apr 20, 2026
2ebd548
Regenerate OpenApi.json to fix duplicate document patch endpoint
lauraneto Apr 20, 2026
114c7ee
Move MimeTypesTransformer to shared base and respect [Consumes]
lauraneto Apr 20, 2026
b67ebe3
Move Umbraco-specific transformers from shared base to API configs
lauraneto Apr 20, 2026
f38eafd
Clarify XML doc for UmbracoOpenApiOptions.Enabled
lauraneto Apr 21, 2026
b89e350
Use alphabetically-first tag across all operations for stable path so…
lauraneto Apr 21, 2026
82dae43
Update MimeTypesTransformer tests for operation transformer interface
lauraneto Apr 21, 2026
d24e2c0
Reference dotnet/aspnetcore#66340 in ReplaceOpenApiSchemaService docs
lauraneto Apr 21, 2026
fc9fb40
Merge branch 'v18/dev' into v18/feature/microsoft-open-api-document-g…
AndyButland Apr 23, 2026
fe82e89
Add unit tests to verify OpenApiSchemaServiceExtensions usage of inte…
AndyButland Apr 23, 2026
435f541
Bumped Microsoft.AspNetCore.OpenApi from 10.0.4 to 10.0.6 to match D…
AndyButland Apr 23, 2026
fada672
Fix indentation.
AndyButland Apr 23, 2026
303eacf
Defensively handle a non-integer status code response key in Response…
AndyButland Apr 23, 2026
cdb41db
Use TryGetValue in RequireNonNullablePropertiesSchemaTransformer to a…
AndyButland Apr 23, 2026
ef9778d
Additional tests and clarifying comments.
AndyButland Apr 23, 2026
7294406
Revert accidental local dev changes to Program.cs, Web.UI.csproj and …
AndyButland Apr 23, 2026
5a54668
Tighten visibility of OpenAPI configuration and transformer classes t…
lauraneto Apr 23, 2026
5752d5b
Merge branch 'v18/dev' into v18/feature/microsoft-open-api-document-g…
lauraneto Apr 24, 2026
69d9afd
Merge branch 'v18/dev' into v18/feature/microsoft-open-api-document-g…
lauraneto Apr 24, 2026
e74d55e
Merge branch 'v18/dev' into v18/feature/microsoft-open-api-document-g…
lauraneto Apr 29, 2026
3d31f6f
Merge remote-tracking branch 'origin/v18/dev' into v18/feature/micros…
lauraneto Apr 29, 2026
d0ad10d
Merge branch 'v18/dev' into v18/feature/microsoft-open-api-document-g…
lauraneto Apr 29, 2026
31d9932
Merge branch 'v18/dev' into v18/feature/microsoft-open-api-document-g…
lauraneto Apr 30, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
<!-- Microsoft packages -->
<ItemGroup>
<PackageVersion Include="Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation" Version="10.0.1" />
<PackageVersion Include="Microsoft.AspNetCore.OpenApi" Version="10.0.2" />
<PackageVersion Include="Microsoft.CodeAnalysis.CSharp" Version="4.14.0" />
<PackageVersion Include="Microsoft.Data.Sqlite" Version="10.0.1" />
<PackageVersion Include="Microsoft.EntityFrameworkCore.Sqlite" Version="10.0.1" />
Expand Down Expand Up @@ -76,7 +77,7 @@
<PackageVersion Include="Serilog.Sinks.Map" Version="2.0.0" />
<PackageVersion Include="SixLabors.ImageSharp" Version="3.1.12" />
<PackageVersion Include="SixLabors.ImageSharp.Web" Version="3.2.0" />
<PackageVersion Include="Swashbuckle.AspNetCore" Version="10.0.1" />
<PackageVersion Include="Swashbuckle.AspNetCore.SwaggerUI" Version="10.0.1" />
</ItemGroup>
<!-- Transitive pinned versions (only required because our direct dependencies have vulnerable versions of transitive dependencies) -->
<ItemGroup>
Expand All @@ -88,4 +89,4 @@
<!-- TODO (V19): Remove these pinned dependencies when the Markdown dependency is removed. -->
<PackageVersion Include="System.Text.RegularExpressions" Version="4.3.1" />
</ItemGroup>
</Project>
</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
using System.Reflection;
using Asp.Versioning;
using Microsoft.AspNetCore.Mvc.Abstractions;
using Microsoft.AspNetCore.Mvc.ApiExplorer;
using Microsoft.AspNetCore.Mvc.Controllers;
using Umbraco.Cms.Api.Common.OpenApi;

namespace Umbraco.Cms.Api.Common.Configuration;

/// <summary>
/// Configures the OpenAPI options for the Default API.
/// </summary>
public class ConfigureDefaultApiOptions : ConfigureUmbracoOpenApiOptionsBase
{
/// <inheritdoc />
protected override string ApiName => DefaultApiConfiguration.ApiName;

/// <inheritdoc />
protected override string ApiTitle => "Default API";

/// <inheritdoc />
protected override string ApiVersion => "Latest";

/// <inheritdoc />
protected override string ApiDescription => "All endpoints not defined under specific APIs";

/// <inheritdoc />
protected override bool ShouldInclude(ApiDescription apiDescription)
{
// Exclude controllers with ExcludeFromDefaultOpenApiDocumentAttribute
if (apiDescription.ActionDescriptor is ControllerActionDescriptor controllerActionDescriptor
&& controllerActionDescriptor.ControllerTypeInfo.GetCustomAttribute<ExcludeFromDefaultOpenApiDocumentAttribute>() is not null)
{
return false;
}

// Include if explicitly mapped to this document
if (base.ShouldInclude(apiDescription))
{
return true;
}

// Include endpoints not explicitly assigned to another document
ApiVersionMetadata apiVersionMetadata = apiDescription.ActionDescriptor.GetApiVersionMetadata();
return string.IsNullOrEmpty(apiVersionMetadata.Name);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
using System.Text.Json.Serialization.Metadata;
using Asp.Versioning;
using Microsoft.AspNetCore.Mvc.Abstractions;
using Microsoft.AspNetCore.Mvc.ApiExplorer;
using Microsoft.AspNetCore.Mvc.Controllers;
using Microsoft.AspNetCore.OpenApi;
using Microsoft.Extensions.Options;
using Microsoft.OpenApi;
using Umbraco.Cms.Api.Common.OpenApi;
using Umbraco.Extensions;

namespace Umbraco.Cms.Api.Common.Configuration;

/// <summary>
/// Base class for configuring OpenAPI options for Umbraco APIs.
/// </summary>
public abstract class ConfigureUmbracoOpenApiOptionsBase : IConfigureNamedOptions<OpenApiOptions>
{
/// <summary>
/// Gets the name/identifier of the API to configure.
/// </summary>
protected abstract string ApiName { get; }

/// <summary>
/// Gets the name/identifier of the API to configure.
/// </summary>
protected abstract string ApiTitle { get; }

/// <summary>
/// Gets the version of the API to configure.
/// </summary>
protected abstract string ApiVersion { get; }

/// <summary>
/// Gets the description of the API to configure.
/// </summary>
protected abstract string ApiDescription { get; }

/// <inheritdoc />
public void Configure(OpenApiOptions options) => Configure(Options.DefaultName, options);

/// <inheritdoc />
public void Configure(string? name, OpenApiOptions options)
{
if (name != ApiName)
{
return;
}

ConfigureOpenApi(options);
}

/// <summary>
/// Configure the OpenAPI options for the specified API.
/// </summary>
/// <param name="options">The <see cref="OpenApiOptions"/> instance to configure.</param>
protected virtual void ConfigureOpenApi(OpenApiOptions options)
{
options.AddDocumentTransformer((document, _, _) =>
{
document.Info = new OpenApiInfo
{
Title = ApiTitle,
Version = ApiVersion,
Description = ApiDescription,
};
document.Servers?.Clear();
return Task.CompletedTask;
});

options.ShouldInclude = ShouldInclude;
options.CreateSchemaReferenceId = CreateSchemaReferenceId;

options.AddOperationTransformer<UmbracoOperationIdTransformer>();

// Tag actions by group name and cleanup unused tags (caused by the tag changes)
options
.AddOperationTransformer<TagActionsByGroupNameTransformer>()
.AddDocumentTransformer<TagActionsByGroupNameTransformer>()
.AddDocumentTransformer<SortTagsAndPathsTransformer>();

options.AddSchemaTransformer<RequireNonNullablePropertiesSchemaTransformer>();
options.AddSchemaTransformer<FixFileReturnTypesTransformer>();
}

/// <summary>
/// Creates a schema reference ID for the given JSON type info.
/// Returns null for types that should be inlined, the default schema ID for non-Umbraco types,
/// or a generated schema ID for Umbraco types.
/// </summary>
/// <param name="jsonTypeInfo">The JSON type info to create a schema reference ID for.</param>
/// <returns>The schema reference ID, or null if the type should be inlined.</returns>
internal static string? CreateSchemaReferenceId(JsonTypeInfo jsonTypeInfo)
{
// Ensure that only types that would normally be included in the schema generation are given a schema reference ID.
// Otherwise, we should return null to inline them.
var defaultSchemaReferenceId = OpenApiOptions.CreateDefaultSchemaReferenceId(jsonTypeInfo);
if (defaultSchemaReferenceId is null)
{
return null;
}

Type targetType = Nullable.GetUnderlyingType(jsonTypeInfo.Type) ?? jsonTypeInfo.Type;

if (targetType.Namespace?.StartsWith("Umbraco.Cms") is not true)
{
return defaultSchemaReferenceId;
}

return UmbracoSchemaIdGenerator.Generate(targetType);
}

/// <summary>
/// Determines whether the specified API description should be included in this OpenAPI document.
/// </summary>
/// <param name="apiDescription">The API description to evaluate.</param>
/// <returns><c>true</c> if the endpoint should be included; otherwise, <c>false</c>.</returns>
protected virtual bool ShouldInclude(ApiDescription apiDescription)
{
if (apiDescription.ActionDescriptor is ControllerActionDescriptor controllerActionDescriptor
&& controllerActionDescriptor.HasMapToApiAttribute(ApiName))
{
return true;
}

ApiVersionMetadata apiVersionMetadata = apiDescription.ActionDescriptor.GetApiVersionMetadata();
return apiVersionMetadata.Name == ApiName;
}
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,33 +1,87 @@
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Options;
using Swashbuckle.AspNetCore.SwaggerUI;
using Umbraco.Cms.Api.Common.Configuration;
using Umbraco.Cms.Api.Common.OpenApi;
using Umbraco.Cms.Api.Common.Serialization;
using Umbraco.Cms.Core;
using Umbraco.Cms.Core.DependencyInjection;
using Umbraco.Cms.Core.Hosting;
using Umbraco.Cms.Web.Common.ApplicationBuilder;
using Umbraco.Extensions;
using IHostingEnvironment = Umbraco.Cms.Core.Hosting.IHostingEnvironment;

namespace Umbraco.Cms.Api.Common.DependencyInjection;

public static class UmbracoBuilderApiExtensions
{
public static IUmbracoBuilder AddUmbracoApiOpenApiUI(this IUmbracoBuilder builder)
{
if (builder.Services.Any(x => !x.IsKeyedService && x.ImplementationType == typeof(OperationIdSelector)))
if (builder.Services.Any(x => !x.IsKeyedService && x.ImplementationType == typeof(UmbracoJsonTypeInfoResolver)))
{
return builder;
}

builder.Services.AddSwaggerGen();
builder.Services.ConfigureOptions<ConfigureUmbracoSwaggerGenOptions>();
builder.Services.AddOptions<UmbracoOpenApiOptions>()
.Configure<IHostingEnvironment, IWebHostEnvironment>((options, hostingEnv, webHostEnv) =>
{
options.Enabled = webHostEnv.IsProduction() is false;
var backOfficePath = hostingEnv.GetBackOfficePath().TrimStart(Constants.CharArrays.ForwardSlash);
options.RouteTemplate = $"{backOfficePath}/openapi/{{documentName}}.json";
options.UiRoutePrefix = $"{backOfficePath}/openapi";
});
builder.Services.AddUmbracoApi<ConfigureDefaultApiOptions>(DefaultApiConfiguration.ApiName, "Default API");
builder.Services.AddSingleton<IUmbracoJsonTypeInfoResolver, UmbracoJsonTypeInfoResolver>();
builder.Services.AddSingleton<IOperationIdSelector, OperationIdSelector>();
builder.Services.AddSingleton<IOperationIdHandler, OperationIdHandler>();
builder.Services.AddSingleton<ISchemaIdSelector, SchemaIdSelector>();
builder.Services.AddSingleton<ISchemaIdHandler, SchemaIdHandler>();
builder.Services.AddSingleton<ISubTypesSelector, SubTypesSelector>();
builder.Services.AddSingleton<ISubTypesHandler, SubTypesHandler>();
builder.Services.AddSingleton<IDocumentInclusionSelector, DocumentInclusionSelector>();
builder.Services.Configure<UmbracoPipelineOptions>(options => options.AddFilter(new SwaggerRouteTemplatePipelineFilter("UmbracoApiCommon")));
builder.Services.Configure<UmbracoPipelineOptions>(options => options.AddFilter(new OpenApiRouteTemplatePipelineFilter("UmbracoApiCommon")));

return builder;
}

/// <summary>
/// Adds and configures an Umbraco API with OpenAPI documentation.
/// </summary>
/// <param name="services">The <see cref="IServiceCollection"/> instance.</param>
/// <param name="apiName">The name/identifier of the API.</param>
/// <param name="apiTitle">The title of the API.</param>
/// <typeparam name="TConfigureOptions">The type used to configure the OpenAPI options.</typeparam>
/// <returns>The <see cref="IServiceCollection"/> instance.</returns>
public static IServiceCollection AddUmbracoApi<TConfigureOptions>(
this IServiceCollection services,
string apiName,
string apiTitle)
where TConfigureOptions : ConfigureUmbracoOpenApiOptionsBase
{
services.AddOpenApi(apiName);
services.ConfigureOptions<TConfigureOptions>();

services.AddOpenApiDocumentToUi(apiName, apiTitle);

return services;
}

/// <summary>
/// Adds an OpenAPI document to the OpenAPI UI document selector dropdown.
/// </summary>
/// <param name="services">The <see cref="IServiceCollection"/> instance.</param>
/// <param name="documentName">The name/identifier of the OpenAPI document.</param>
/// <param name="documentTitle">The title to display in the UI dropdown. Defaults to <paramref name="documentName"/> if not specified.</param>
/// <returns>The <see cref="IServiceCollection"/> instance.</returns>
public static IServiceCollection AddOpenApiDocumentToUi(
this IServiceCollection services,
string documentName,
string? documentTitle = null)
{
services.AddOptions<SwaggerUIOptions>()
.Configure<IOptions<UmbracoOpenApiOptions>>((swaggerUiOptions, openApiOptions) =>
{
var openApiRoute = openApiOptions.Value.RouteTemplate.Replace("{documentName}", documentName).EnsureStartsWith("/");
swaggerUiOptions.SwaggerEndpoint(openApiRoute, documentTitle ?? documentName);
swaggerUiOptions.ConfigObject.Urls = swaggerUiOptions.ConfigObject.Urls.OrderBy(x => x.Name);
});

return services;
}
}
Loading
Loading