Skip to content

Commit

Permalink
Merge pull request #5396 from dfe-analytical-services/ees-5663
Browse files Browse the repository at this point in the history
EES-5663 Tweaks to public API versioning
  • Loading branch information
ntsim authored Nov 22, 2024
2 parents 0d73718 + 0c204af commit 6641041
Show file tree
Hide file tree
Showing 15 changed files with 181 additions and 16 deletions.
2 changes: 1 addition & 1 deletion infrastructure/templates/template.json
Original file line number Diff line number Diff line change
Expand Up @@ -2114,7 +2114,7 @@
"NEXT_CONFIG_MODE": "server",
"NODE_ENV": "production",
"PUBLIC_URL": "[concat(variables('publicAppUrl'), '/')]",
"PUBLIC_API_BASE_URL": "[concat('https://', parameters('publicApiUrl'),'/api/v1.0')]",
"PUBLIC_API_BASE_URL": "[concat('https://', parameters('publicApiUrl'), '/v1')]",
"PUBLIC_API_DOCS_URL": "[concat('https://', parameters('publicApiDocsUrl'))]",
"WEBSITE_NODE_DEFAULT_VERSION": "20.16.0",
"WEBSITES_PORT": 3000
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public async Task<Either<ActionResult, HttpResponseMessage>> GetDataSetVersionCh
{
return await SendRequest(
() => httpClient.GetAsync(
$"api/v1/data-sets/{dataSetId}/versions/{dataSetVersion}/changes",
$"v1/data-sets/{dataSetId}/versions/{dataSetVersion}/changes",
cancellationToken
),
cancellationToken
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ namespace GovUk.Education.ExploreEducationStatistics.Public.Data.Api.Tests.Contr

public abstract class DataSetVersionsControllerTests(TestApplicationFactory testApp) : IntegrationTestFixture(testApp)
{
private const string BaseUrl = "api/v1/data-sets";
private const string BaseUrl = "v1/data-sets";

public class ListDataSetVersionsTests(TestApplicationFactory testApp) : DataSetVersionsControllerTests(testApp)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ namespace GovUk.Education.ExploreEducationStatistics.Public.Data.Api.Tests.Contr

public abstract class DataSetsControllerGetQueryTests(TestApplicationFactory testApp) : IntegrationTestFixture(testApp)
{
private const string BaseUrl = "api/v1/data-sets";
private const string BaseUrl = "v1/data-sets";

private readonly TestDataSetVersionPathResolver _dataSetVersionPathResolver = new()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ namespace GovUk.Education.ExploreEducationStatistics.Public.Data.Api.Tests.Contr

public abstract class DataSetsControllerPostQueryTests(TestApplicationFactory testApp) : IntegrationTestFixture(testApp)
{
private const string BaseUrl = "api/v1/data-sets";
private const string BaseUrl = "v1/data-sets";

private readonly TestDataSetVersionPathResolver _dataSetVersionPathResolver = new()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ namespace GovUk.Education.ExploreEducationStatistics.Public.Data.Api.Tests.Contr

public abstract class DataSetsControllerTests(TestApplicationFactory testApp) : IntegrationTestFixture(testApp)
{
private const string BaseUrl = "api/v1/data-sets";
private const string BaseUrl = "v1/data-sets";

public class GetDataSetTests(TestApplicationFactory testApp) : DataSetsControllerTests(testApp)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ namespace GovUk.Education.ExploreEducationStatistics.Public.Data.Api.Tests.Contr

public abstract class PublicationsControllerTests(TestApplicationFactory testApp) : IntegrationTestFixture(testApp)
{
private const string BaseUrl = "api/v1/publications";
private const string BaseUrl = "v1/publications";

public class ListPublicationsTests(TestApplicationFactory testApp) : PublicationsControllerTests(testApp)
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
using System.Text.Json;
using GovUk.Education.ExploreEducationStatistics.Public.Data.Api.Swagger;
using Microsoft.OpenApi.Models;
using Swashbuckle.AspNetCore.SwaggerGen;

namespace GovUk.Education.ExploreEducationStatistics.Public.Data.Api.Tests.Swagger;

public class VersionedPathsDocumentFilterTests
{
[Fact]
public void VersionsInlinedIntoPaths()
{
var document = new OpenApiDocument
{
Info = new OpenApiInfo { Version = "1" },
Paths = new OpenApiPaths
{
{"/v{version}/endpoint-1", new OpenApiPathItem()},
{"/v{version}/endpoint-2/{id}", new OpenApiPathItem()}
}
};

var filter = new VersionedPathsDocumentFilter();
var context = CreateDocumentFilterContext();

filter.Apply(document, context);

Assert.Equal(2, document.Paths.Count);
Assert.Contains("/v1/endpoint-1", document.Paths.Keys);
Assert.Contains("/v1/endpoint-2/{id}", document.Paths.Keys);
}

[Fact]
public void VersionParametersRemoved()
{
var document = new OpenApiDocument
{
Info = new OpenApiInfo { Version = "1" },
Paths = new OpenApiPaths
{
{
"/v{version}/endpoint-1",
new OpenApiPathItem
{
Parameters =
[
new OpenApiParameter { Name = "version" }
],
Operations =
{
{
OperationType.Get,
new OpenApiOperation
{
Parameters =
[
new OpenApiParameter { Name = "version" }
]
}
}

}
}
},
{
"/v{version}/endpoint-2/{id}",
new OpenApiPathItem
{
Parameters =
[
new OpenApiParameter { Name = "version" },
new OpenApiParameter { Name = "id" }
],
Operations =
{
{
OperationType.Get,
new OpenApiOperation
{
Parameters =
[
new OpenApiParameter { Name = "version" },
new OpenApiParameter { Name = "id" }
]
}
}

}
}
}
}
};

var filter = new VersionedPathsDocumentFilter();
var context = CreateDocumentFilterContext();

filter.Apply(document, context);

Assert.Equal(2, document.Paths.Count);

var endpoint1Paths = document.Paths["/v1/endpoint-1"];

Assert.Empty(endpoint1Paths.Parameters);
Assert.Empty(endpoint1Paths.Operations[OperationType.Get].Parameters);

var endpoint2Paths = document.Paths["/v1/endpoint-2/{id}"];

Assert.Single(endpoint2Paths.Parameters);
Assert.Equal("id", endpoint2Paths.Parameters[0].Name);

Assert.Single(endpoint2Paths.Operations[OperationType.Get].Parameters);
Assert.Equal("id", endpoint2Paths.Parameters[0].Name);
}

private static DocumentFilterContext CreateDocumentFilterContext()
{
var schemaGenerator = new SchemaGenerator(
new SchemaGeneratorOptions(),
new JsonSerializerDataContractResolver(
new JsonSerializerOptions
{
PropertyNamingPolicy = JsonNamingPolicy.CamelCase
}
)
);
var schemaRepository = new SchemaRepository();

return new DocumentFilterContext([], schemaGenerator, schemaRepository);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@

namespace GovUk.Education.ExploreEducationStatistics.Public.Data.Api.Controllers;

[ApiVersion(1.0)]
[ApiVersion("1")]
[ApiController]
[Route("api/v{version:apiVersion}/data-sets/{dataSetId:guid}/versions")]
[Route("v{version:apiVersion}/data-sets/{dataSetId:guid}/versions")]
public class DataSetVersionsController(
IDataSetService dataSetService,
IDataSetVersionChangeService dataSetVersionChangeService)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@

namespace GovUk.Education.ExploreEducationStatistics.Public.Data.Api.Controllers;

[ApiVersion(1.0)]
[ApiVersion("1")]
[ApiController]
[Route("api/v{version:apiVersion}/data-sets")]
[Route("v{version:apiVersion}/data-sets")]
public class DataSetsController(
IDataSetService dataSetService,
IDataSetQueryService dataSetQueryService)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@

namespace GovUk.Education.ExploreEducationStatistics.Public.Data.Api.Controllers;

[ApiVersion(1.0)]
[ApiVersion("1")]
[ApiController]
[Route("api/v{version:apiVersion}/publications")]
[Route("v{version:apiVersion}/publications")]
public class PublicationsController(IPublicationService publicationService, IDataSetService dataSetService)
: ControllerBase
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@

app.UseSwagger(options =>
{
options.RouteTemplate = "/swagger/{documentName}/openapi.json";
options.RouteTemplate = "/swagger/v{documentName}/openapi.json";
});
app.UseSwaggerUI(options =>
{
Expand All @@ -48,7 +48,7 @@
foreach (var description in app.DescribeApiVersions())
{
options.SwaggerEndpoint(
url: $"/swagger/{description.GroupName}/openapi.json",
url: $"/swagger/v{description.GroupName}/openapi.json",
name: $"v{description.GroupName}");
}
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,11 @@ public class SwaggerConfig(
{
public void Configure(SwaggerGenOptions options)
{
options.DocumentFilter<VersionedPathsDocumentFilter>();

options.OperationFilter<DefaultValuesOperationFilter>();
options.OperationFilter<GeneralResponseOperationFilter>();

options.SchemaFilter<JsonConverterSchemaFilter>();
options.SchemaFilter<RequiredPropertySchemaFilter>();
options.SchemaFilter<SwaggerEnumSchemaFilter>();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
using Microsoft.OpenApi.Models;
using Swashbuckle.AspNetCore.SwaggerGen;

namespace GovUk.Education.ExploreEducationStatistics.Public.Data.Api.Swagger;

public class VersionedPathsDocumentFilter : IDocumentFilter
{
public void Apply(OpenApiDocument document, DocumentFilterContext context)
{
var newPaths = new OpenApiPaths();

foreach (var path in document.Paths)
{
var versionedPath = path.Key.Replace("{version}", document.Info.Version);

newPaths[versionedPath] = path.Value;

path.Value.Parameters = path.Value.Parameters
.Where(p => p.Name != "version")
.ToList();

foreach (var operation in path.Value.Operations.Values)
{
operation.Parameters = operation.Parameters
.Where(p => p.Name != "version")
.ToList();
}
}

document.Paths = newPaths;
}
}
2 changes: 1 addition & 1 deletion src/explore-education-statistics-frontend/.env
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
CONTENT_API_BASE_URL=http://localhost:5010/api
DATA_API_BASE_URL=http://localhost:5000/api
PUBLIC_API_BASE_URL=http://localhost:5050/api/v1.0
PUBLIC_API_BASE_URL=http://localhost:5050/v1
PUBLIC_API_DOCS_URL=https://dev.statistics.api.education.gov.uk/docs
NOTIFICATION_API_BASE_URL=http://localhost:7073/api
GA_TRACKING_ID=
Expand Down

0 comments on commit 6641041

Please sign in to comment.