diff --git a/PxWeb/Config/Api2/PxApiConfigurationOptions.cs b/PxWeb/Config/Api2/PxApiConfigurationOptions.cs index cbad873e..225344ed 100644 --- a/PxWeb/Config/Api2/PxApiConfigurationOptions.cs +++ b/PxWeb/Config/Api2/PxApiConfigurationOptions.cs @@ -15,6 +15,7 @@ public class PxApiConfigurationOptions public int CacheTime { get; set; } = 5; public int PageSize { get; set; } public string BaseURL { get; set; } = String.Empty; + public string RoutePrefix { get; set; } = String.Empty; public List OutputFormats { get; set; } = new List(); public string DefaultOutputFormat { get; set; } = String.Empty; diff --git a/PxWeb/Controllers/Api2/Admin/CacheController.cs b/PxWeb/Controllers/Api2/Admin/CacheController.cs index 8916eb52..eb502374 100644 --- a/PxWeb/Controllers/Api2/Admin/CacheController.cs +++ b/PxWeb/Controllers/Api2/Admin/CacheController.cs @@ -15,7 +15,7 @@ public CacheController(IPxCache pxCache) } [HttpDelete] - [Route("/api/v2/admin/cache")] + [Route("/admin/cache")] public IActionResult Clear() { _pxCache.Clear(); diff --git a/PxWeb/Controllers/Api2/Admin/DatabaseController.cs b/PxWeb/Controllers/Api2/Admin/DatabaseController.cs index c129f629..7cb678b1 100644 --- a/PxWeb/Controllers/Api2/Admin/DatabaseController.cs +++ b/PxWeb/Controllers/Api2/Admin/DatabaseController.cs @@ -45,7 +45,7 @@ public DatabaseController(IControllerStateProvider stateProvider, BackgroundWork } [HttpPut] - [Route("/api/v2/admin/database")] + [Route("/admin/database")] [SwaggerOperation("Database")] [SwaggerResponse(statusCode: 202, description: "Accepted")] [SwaggerResponse(statusCode: 401, description: "Unauthorized")] @@ -109,7 +109,7 @@ internal async Task createMenuXml(bool? langDependent, string? sortOrder, Cancel } [HttpGet] - [Route("/api/v2/admin/database")] + [Route("/admin/database")] [SwaggerOperation("Database")] [SwaggerResponse(statusCode: 200, description: "Success")] [SwaggerResponse(statusCode: 401, description: "Unauthorized")] diff --git a/PxWeb/Controllers/Api2/Admin/SearchindexController.cs b/PxWeb/Controllers/Api2/Admin/SearchindexController.cs index f23f3d72..bab95459 100644 --- a/PxWeb/Controllers/Api2/Admin/SearchindexController.cs +++ b/PxWeb/Controllers/Api2/Admin/SearchindexController.cs @@ -43,7 +43,7 @@ public SearchindexController(BackgroundWorkerQueue backgroundWorkerQueue, IContr /// /// [HttpPost] - [Route("/api/v2/admin/searchindex")] + [Route("/admin/searchindex")] [SwaggerOperation("IndexDatabase")] [SwaggerResponse(statusCode: 202, description: "Accepted")] [SwaggerResponse(statusCode: 401, description: "Unauthorized")] @@ -84,7 +84,7 @@ public IActionResult IndexDatabase() /// /// [HttpPatch] - [Route("/api/v2/admin/searchindex")] + [Route("/admin/searchindex")] [SwaggerOperation("IndexDatabase")] [SwaggerResponse(statusCode: 202, description: "Accepted")] [SwaggerResponse(statusCode: 401, description: "Unauthorized")] @@ -135,7 +135,7 @@ public IActionResult IndexDatabase([FromBody, Required] string[] tables) } [HttpGet] - [Route("/api/v2/admin/searchindex")] + [Route("/admin/searchindex")] [SwaggerOperation("IndexDatabase")] [SwaggerResponse(statusCode: 200, description: "Success")] [SwaggerResponse(statusCode: 401, description: "Unauthorized")] diff --git a/PxWeb/Controllers/Api2/NavigationApiController.cs b/PxWeb/Controllers/Api2/NavigationApiController.cs index 4b6debba..06c74280 100644 --- a/PxWeb/Controllers/Api2/NavigationApiController.cs +++ b/PxWeb/Controllers/Api2/NavigationApiController.cs @@ -45,7 +45,7 @@ public NavigationApiController(IDataSource dataSource, ILanguageHelper languageH /// /// Gets navigation item with the given id. /// HttpGet - /// Route /api/v2/navigation/{id} + /// Route /navigation/{id} /// /// Id /// The language if the default is not what you want. @@ -61,7 +61,7 @@ public override IActionResult GetNavigationById([FromRoute(Name = "id"), Require /// /// Browse the database structure /// HttpGet - /// Route /api/v2/navigation + /// Route /navigation /// /// The language if the default is not what you want. /// Success diff --git a/PxWeb/Mappers/LinkCreator.cs b/PxWeb/Mappers/LinkCreator.cs index 251ce2ec..72674690 100644 --- a/PxWeb/Mappers/LinkCreator.cs +++ b/PxWeb/Mappers/LinkCreator.cs @@ -99,6 +99,7 @@ private string CreateURL(string endpointUrl, string language, bool showLangParam StringBuilder sb = new StringBuilder(); sb.Append(_urlBase); + sb.Append("/"); sb.Append(endpointUrl); if (showLangParam) @@ -114,6 +115,7 @@ private string CreatePageURL(string endpointUrl, string language, bool showLangP StringBuilder sb = new StringBuilder(); sb.Append(_urlBase); + sb.Append("/"); sb.Append(endpointUrl); if (!string.IsNullOrEmpty(query) && showLangParam) diff --git a/PxWeb/Middleware/GlobalRoutePrefixMiddleware.cs b/PxWeb/Middleware/GlobalRoutePrefixMiddleware.cs new file mode 100644 index 00000000..518dd356 --- /dev/null +++ b/PxWeb/Middleware/GlobalRoutePrefixMiddleware.cs @@ -0,0 +1,25 @@ +using System.Threading.Tasks; + +using Microsoft.AspNetCore.Http; + +namespace PxWeb.Middleware +{ + + public class GlobalRoutePrefixMiddleware + { + private readonly RequestDelegate _next; + private readonly string _routePrefix; + + public GlobalRoutePrefixMiddleware(RequestDelegate next, string routePrefix) + { + _next = next; + _routePrefix = routePrefix; + } + + public async Task InvokeAsync(HttpContext context) + { + context.Request.PathBase = new PathString(_routePrefix); + await _next(context); + } + } +} diff --git a/PxWeb/Program.cs b/PxWeb/Program.cs index e19fc7ac..d14d0c71 100644 --- a/PxWeb/Program.cs +++ b/PxWeb/Program.cs @@ -6,10 +6,12 @@ using log4net; using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Http; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; +using Microsoft.OpenApi.Models; using Newtonsoft.Json.Converters; using Newtonsoft.Json.Serialization; @@ -129,6 +131,12 @@ public static void Main(string[] args) { // Sort endpoints c.OrderActionsBy((apiDesc) => $"{apiDesc.ActionDescriptor.RouteValues["controller"]}_{apiDesc.RelativePath}"); + c.SwaggerDoc("v2", new OpenApiInfo + { + Title = "PxWebApi", + Version = "v2-beta" + } + ); }); @@ -136,12 +144,19 @@ public static void Main(string[] args) bool corsEnbled = builder.Services.ConfigurePxCORS(builder, _logger); var app = builder.Build(); + var routePrefix = builder.Configuration.GetSection("PxApiConfiguration:RoutePrefix").Value; + + app.UseMiddleware(routePrefix); + app.UsePathBase(new PathString(routePrefix)); // Configure the HTTP request pipeline. if (app.Environment.IsDevelopment()) { app.UseSwagger(); - app.UseSwaggerUI(); + app.UseSwaggerUI(options => + { + options.SwaggerEndpoint("/swagger/v2/swagger.json", "PxWebApi 2.0-beta"); + }); } app.UseHttpsRedirection(); @@ -156,7 +171,7 @@ public static void Main(string[] args) { app.UseAuthorization(); - app.UseWhen(context => context.Request.Path.StartsWithSegments("/api/v2/admin"), appBuilder => + app.UseWhen(context => context.Request.Path.StartsWithSegments(routePrefix + "/admin") || context.Request.Path.StartsWithSegments("/admin"), appBuilder => { appBuilder.UseAdminProtectionIpWhitelist(); appBuilder.UseAdminProtectionKey(); @@ -169,7 +184,7 @@ public static void Main(string[] args) app.UseIpRateLimiting(); } - app.UseWhen(context => !context.Request.Path.StartsWithSegments("/api/v2/admin"), appBuilder => + app.UseWhen(context => !context.Request.Path.StartsWithSegments(routePrefix + "/admin") || context.Request.Path.StartsWithSegments("/admin"), appBuilder => { appBuilder.UseCacheMiddleware(); }); diff --git a/PxWeb/PxWeb.csproj b/PxWeb/PxWeb.csproj index 2d4cf83f..d8450dd1 100644 --- a/PxWeb/PxWeb.csproj +++ b/PxWeb/PxWeb.csproj @@ -39,7 +39,7 @@ - + diff --git a/PxWeb/appsettings.json b/PxWeb/appsettings.json index 7731efa2..a7bc6758 100644 --- a/PxWeb/appsettings.json +++ b/PxWeb/appsettings.json @@ -39,7 +39,8 @@ "CacheTime": 86400, "SearchEngine": "Lucene", "PageSize": 20, - "BaseURL": "https://www.pxapi.com/api/v2/", + "BaseURL": "https://www.pxapi.com/api/v2", + "RoutePrefix": "/api/v2", "OutputFormats": [ "xlsx", "xlsx_doublecolumn", diff --git a/PxWebApi.BigTests/AdminDatabaseController/test_appsettings.json b/PxWebApi.BigTests/AdminDatabaseController/test_appsettings.json index 5d29a57f..5200f64c 100644 --- a/PxWebApi.BigTests/AdminDatabaseController/test_appsettings.json +++ b/PxWebApi.BigTests/AdminDatabaseController/test_appsettings.json @@ -39,7 +39,8 @@ "CacheTime": 86400, "SearchEngine": "Lucene", "PageSize": 20, - "BaseURL": "https://www.pxapi.com/api/v2/", + "BaseURL": "https://www.pxapi.com/api/v2", + "RoutePrefix": "/api/v2", "OutputFormats": [ "xlsx", "xlsx_doublecolumn", diff --git a/PxWebApi.BigTests/ConfigController/test_appsettings.json b/PxWebApi.BigTests/ConfigController/test_appsettings.json index 93b0574c..ac527803 100644 --- a/PxWebApi.BigTests/ConfigController/test_appsettings.json +++ b/PxWebApi.BigTests/ConfigController/test_appsettings.json @@ -40,7 +40,8 @@ "CacheTime": 86400, "SearchEngine": "Lucene", "PageSize": 20, - "BaseURL": "https://www.pxapi.com/api/v2/", + "BaseURL": "https://www.pxapi.com/api/v2", + "RoutePrefix": "/api/v2", "OutputFormats": [ "xlsx", "xlsx_doublecolumn", diff --git a/PxWebApi.BigTests/TableController/test_appsettings.json b/PxWebApi.BigTests/TableController/test_appsettings.json index 93b0574c..ac527803 100644 --- a/PxWebApi.BigTests/TableController/test_appsettings.json +++ b/PxWebApi.BigTests/TableController/test_appsettings.json @@ -40,7 +40,8 @@ "CacheTime": 86400, "SearchEngine": "Lucene", "PageSize": 20, - "BaseURL": "https://www.pxapi.com/api/v2/", + "BaseURL": "https://www.pxapi.com/api/v2", + "RoutePrefix": "/api/v2", "OutputFormats": [ "xlsx", "xlsx_doublecolumn",