diff --git a/Emby.Server.Implementations/Browser/BrowserLauncher.cs b/Emby.Server.Implementations/Browser/BrowserLauncher.cs
index 96096e142a..e706401fd1 100644
--- a/Emby.Server.Implementations/Browser/BrowserLauncher.cs
+++ b/Emby.Server.Implementations/Browser/BrowserLauncher.cs
@@ -1,5 +1,7 @@
using System;
using MediaBrowser.Controller;
+using MediaBrowser.Controller.Configuration;
+using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
namespace Emby.Server.Implementations.Browser
@@ -24,7 +26,7 @@ namespace Emby.Server.Implementations.Browser
/// The app host.
public static void OpenSwaggerPage(IServerApplicationHost appHost)
{
- TryOpenUrl(appHost, "/swagger/index.html");
+ TryOpenUrl(appHost, "/api-docs/swagger");
}
///
diff --git a/Jellyfin.Api/Jellyfin.Api.csproj b/Jellyfin.Api/Jellyfin.Api.csproj
index 8f23ef9d03..77bb52c6a5 100644
--- a/Jellyfin.Api/Jellyfin.Api.csproj
+++ b/Jellyfin.Api/Jellyfin.Api.csproj
@@ -10,7 +10,8 @@
-
+
+
diff --git a/Jellyfin.Server/Extensions/ApiApplicationBuilderExtensions.cs b/Jellyfin.Server/Extensions/ApiApplicationBuilderExtensions.cs
index 0bd654c7dc..745567703f 100644
--- a/Jellyfin.Server/Extensions/ApiApplicationBuilderExtensions.cs
+++ b/Jellyfin.Server/Extensions/ApiApplicationBuilderExtensions.cs
@@ -1,4 +1,4 @@
-using Jellyfin.Server.Middleware;
+using MediaBrowser.Controller.Configuration;
using Microsoft.AspNetCore.Builder;
namespace Jellyfin.Server.Extensions
@@ -12,17 +12,39 @@ namespace Jellyfin.Server.Extensions
/// Adds swagger and swagger UI to the application pipeline.
///
/// The application builder.
+ /// The server configuration.
/// The updated application builder.
- public static IApplicationBuilder UseJellyfinApiSwagger(this IApplicationBuilder applicationBuilder)
+ public static IApplicationBuilder UseJellyfinApiSwagger(
+ this IApplicationBuilder applicationBuilder,
+ IServerConfigurationManager serverConfigurationManager)
{
- applicationBuilder.UseSwagger();
-
// Enable middleware to serve swagger-ui (HTML, JS, CSS, etc.),
// specifying the Swagger JSON endpoint.
- return applicationBuilder.UseSwaggerUI(c =>
+
+ var baseUrl = serverConfigurationManager.Configuration.BaseUrl.Trim('/');
+ if (!string.IsNullOrEmpty(baseUrl))
{
- c.SwaggerEndpoint("/swagger/v1/swagger.json", "Jellyfin API V1");
- });
+ baseUrl += '/';
+ }
+
+ return applicationBuilder
+ .UseSwagger(c =>
+ {
+ // Custom path requires {documentName}, SwaggerDoc documentName is 'api-docs'
+ c.RouteTemplate = $"/{baseUrl}{{documentName}}/openapi.json";
+ })
+ .UseSwaggerUI(c =>
+ {
+ c.DocumentTitle = "Jellyfin API";
+ c.SwaggerEndpoint($"/{baseUrl}api-docs/openapi.json", "Jellyfin API");
+ c.RoutePrefix = $"{baseUrl}api-docs/swagger";
+ })
+ .UseReDoc(c =>
+ {
+ c.DocumentTitle = "Jellyfin API";
+ c.SpecUrl($"/{baseUrl}api-docs/openapi.json");
+ c.RoutePrefix = $"{baseUrl}api-docs/redoc";
+ });
}
}
}
diff --git a/Jellyfin.Server/Extensions/ApiServiceCollectionExtensions.cs b/Jellyfin.Server/Extensions/ApiServiceCollectionExtensions.cs
index 00688074f0..a354f45aad 100644
--- a/Jellyfin.Server/Extensions/ApiServiceCollectionExtensions.cs
+++ b/Jellyfin.Server/Extensions/ApiServiceCollectionExtensions.cs
@@ -1,3 +1,8 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text.Json.Serialization;
using Jellyfin.Api;
using Jellyfin.Api.Auth;
using Jellyfin.Api.Auth.FirstTimeSetupOrElevatedPolicy;
@@ -91,7 +96,22 @@ namespace Jellyfin.Server.Extensions
{
return serviceCollection.AddSwaggerGen(c =>
{
- c.SwaggerDoc("v1", new OpenApiInfo { Title = "Jellyfin API", Version = "v1" });
+ c.SwaggerDoc("api-docs", new OpenApiInfo { Title = "Jellyfin API" });
+
+ // Add all xml doc files to swagger generator.
+ var xmlFiles = Directory.GetFiles(
+ AppContext.BaseDirectory,
+ "*.xml",
+ SearchOption.TopDirectoryOnly);
+
+ foreach (var xmlFile in xmlFiles)
+ {
+ c.IncludeXmlComments(xmlFile);
+ }
+
+ // Order actions by route path, then by http method.
+ c.OrderActionsBy(description =>
+ $"{description.ActionDescriptor.RouteValues["controller"]}_{description.HttpMethod}");
});
}
}
diff --git a/Jellyfin.Server/Program.cs b/Jellyfin.Server/Program.cs
index e55b0d4ed9..7135800802 100644
--- a/Jellyfin.Server/Program.cs
+++ b/Jellyfin.Server/Program.cs
@@ -529,7 +529,7 @@ namespace Jellyfin.Server
var inMemoryDefaultConfig = ConfigurationOptions.DefaultConfiguration;
if (startupConfig != null && !startupConfig.HostWebClient())
{
- inMemoryDefaultConfig[HttpListenerHost.DefaultRedirectKey] = "swagger/index.html";
+ inMemoryDefaultConfig[HttpListenerHost.DefaultRedirectKey] = "api-docs/swagger";
}
return config
diff --git a/Jellyfin.Server/Startup.cs b/Jellyfin.Server/Startup.cs
index b17357fc3d..7c49afbfc6 100644
--- a/Jellyfin.Server/Startup.cs
+++ b/Jellyfin.Server/Startup.cs
@@ -69,7 +69,7 @@ namespace Jellyfin.Server
app.Use(serverApplicationHost.ExecuteWebsocketHandlerAsync);
// TODO use when old API is removed: app.UseAuthentication();
- app.UseJellyfinApiSwagger();
+ app.UseJellyfinApiSwagger(_serverConfigurationManager);
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>